go语言的并发实现起来很简单,只需要一个go关键字即可使函数并发,但是捕捉并发方法中的错误就没有那么方便了。
本文总结在go语言中,并发时处理异常的一个方法。
channal.go
这个go文件中,有两个函数sum和sub,如果第一个int比第二个int小的话就抛出错误,否则正常运行。
package main
import (
"errors"
"fmt"
"sync"
)
type calculate func(int, int, *sync.WaitGroup) (int, error)
func main() {
wg := &sync.WaitGroup{}
cals := []calculate{sum, sub}
for _, v := range cals {
wg.Add(1)
go v(1, 2, wg)
}
wg.Wait()
}
func sum(a int, b int, wg *sync.WaitGroup) (int, error) {
defer wg.Done()
fmt.Println(a + b)
if a > b {
return a + b, nil
}
return 0, errors.New("a is smaller than b")
}
func sub(a int, b int, wg *sync.WaitGroup) (int, error) {
defer wg.Done()
fmt.Println(a - b)
if a > b {
return a - b, nil
}
return 0, errors.New("a is smaller than b")
}
目前看起来没有什么问题。但是该怎么处理sum和sub抛出的错误呢?
解决方法
创建一个struct用来存放协程里面抛出的错误。
type results struct {
result int
err error
}
完整代码
package main
import (
"errors"
"fmt"
"sync"
)
type calculate func(int, int) (int, error)
type results struct {
result int
err error
}
func main() {
wg := &sync.WaitGroup{}
cals := []calculate{sum, sub}
resultchan := make(chan results, len(cals))
for _, v := range cals {
wg.Add(1)
go func(cal calculate) {
result, err := cal(3, 2)
resultchan <- results{result, err}
wg.Done()
}(v)
}
wg.Wait()
close(resultchan)
for v := range resultchan {
if v.err != nil {
fmt.Println(v.err)
continue
}
fmt.Println(v.result)
}
}
func sum(a int, b int) (int, error) {
if a > b {
return a + b, nil
}
return 0, errors.New("a is smaller than b")
}
func sub(a int, b int) (int, error) {
if a > b {
return a - b, nil
}
return 0, errors.New("a is smaller than b")
}
网友评论