go goroutine 怎样进行错误处理


Posted in Golang onJuly 16, 2021

前言

在 Go 语言程序开发中,goroutine 的使用是比较频繁的,因此在日常编码的时候 goroutine 里的错误处理,怎么做会比较好呢?

一般我们的业务代码如下:

func main() {
 var wg sync.WaitGroup
 wg.Add(2)
 go func() {
  //... 业务逻辑
  wg.Done()
 }()
 go func() {
  //... 业务逻辑
  wg.Done()
 }()
 wg.Wait()
}

在上面的代码中,我们运行了多个 goroutine,每个协程又是单独行动的,想要抛出 error 错误信息,也不怎么明智。

通过错误日志记录

常用的第一种方法:通过把错误记录写入到日志文件中,再结合相关的 logtail 进行采集和梳理。

但这又会引入新的问题,那就是调用错误日志的方法写的到处都是,代码结构也比较乱、不直观。

最重要的是无法针对 error 做特定的逻辑处理和流转。

利用 channel 传输

大家可能会想到 Go 的经典哲学:不要通过共享内存来通信,而是通过通信来实现内存共享(Do not communicate by sharing memory; instead, share memory by communicating)。

第二种方法:利用 channel 来传输多个 goroutine 中的 errors:

func main() {
 cherrors := make(chan error)
 wgDone := make(chan bool)

 var wg sync.WaitGroup
 wg.Add(2)
 go func() {
  //... 业务逻辑
  wg.Done()
 }()
 go func() {
  //... 业务逻辑
  err := returnErr()
  if err != nil {
   cherrors <- err
  }
  wg.Done()
 }()
 go func() {
  wg.Wait()
  close(wgDone)
 }()

 select {
 case <-wgDone:
  break
 case err := <-cherrors:
  close(cherrors)
  fmt.Println(err)
 }

 time.Sleep(time.Second)
}

func returnErr() error {
 return errors.New("出错啦。。我是错误信息")
}

虽然使用 channel 后已经方便了不少,但编写 channel 还要关心一些非业务向的逻辑。

使用 sync/errgroup

第三种方法,就是使用官方提供的 golang.org/x/sync/errgroup 标准库:

type Group
    func WithContext(ctx context.Context) (*Group, context.Context)
    func (g *Group) Go(f func() error)
    func (g *Group) Wait() error
  • Go:启动一个协程,在新的 goroutine 中调用给定的函数。
  • Wait:等待协程结束,直到 Go 方法中的所有函数调用都返回,然后返回其中第一个非零错误(如果有错误的话)。

结合其特性能够非常便捷的针对多 goroutine 进行错误处理:

func main() {
 group := new(errgroup.Group)

 nums := []int{-1, 0, 1}
 for _, num := range nums {
  num := num
  group.Go(func() error {
   res, err := output(num)
   fmt.Println(res)
   return err
  })
 }

 if err := group.Wait(); err != nil {
  fmt.Println("Get errors: ", err)
 } else {
  fmt.Println("Get all num successfully!")
 }
}

func output(num int) (int, error) {
 if num < 0 {
  return 0, errors.New("math: square root error!")
 }
 return num, nil
}

每启动一个新的 goroutine 都直接使用 Group.Go 方法,在等待和错误处理上使用 Group.Wait 方法。

这种方法进行错误处理的好处是不需要关注非业务逻辑的控制代码,比较简洁明了。

总结

在 Go 语言中,goroutine 是一种常用的方法,为此我们需要更了解 goroutine 的一系列相关知识,像是 context、error处理等

在团队开发中,统一一定的规范,这样的代码阅读起来就会比较明朗,一些隐藏很深的 Bug 也会减少很多。

到此这篇关于go goroutine 怎样进行错误处理的文章就介绍到这了,更多相关go goroutine 错误处理内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Golang 相关文章推荐
win10下go mod配置方式
Apr 25 Golang
golang 实现两个结构体复制字段
Apr 28 Golang
使用Golang的channel交叉打印两个数组的操作
Apr 29 Golang
Golang中异常处理机制详解
Jun 08 Golang
浅谈Golang 切片(slice)扩容机制的原理
Jun 09 Golang
Go语言的协程上下文的几个方法和用法
Apr 11 Golang
golang连接MySQl使用sqlx库
Apr 14 Golang
golang使用map实现去除重复数组
Apr 14 Golang
Go获取两个时区的时间差
Apr 20 Golang
GoFrame基于性能测试得知grpool使用场景
Jun 21 Golang
Go微服务项目配置文件的定义和读取示例详解
Jun 21 Golang
Go gorilla securecookie库的安装使用详解
Aug 14 Golang
go开发alertmanger实现钉钉报警
Jul 16 #Golang
K8s部署发布Golang应用程序的实现方法
Jul 16 #Golang
入门学习Go的基本语法
Jul 07 #Golang
golang中字符串MD5生成方式总结
Jul 04 #Golang
golang fmt格式“占位符”的实例用法详解
Jul 04 #Golang
Go语言空白表示符_的实例用法
Jul 04 #Golang
Go 语言结构实例分析
Jul 04 #Golang
You might like
Yii中CGridView关联表搜索排序方法实例详解
2014/12/03 PHP
PHP判断网络文件是否存在的方法
2015/03/12 PHP
PHP通过串口实现发送短信
2015/07/08 PHP
浅析PHP中的闭包和匿名函数
2017/12/25 PHP
PHP创建XML接口示例
2019/07/04 PHP
jquery中获取元素的几种方式小结
2011/07/05 Javascript
22点关于jquery性能优化的建议
2014/05/28 Javascript
浅析Node.js查找字符串功能
2014/09/03 Javascript
js控制网页前进和后退的方法
2015/06/08 Javascript
JavaScript实现函数返回多个值的方法
2015/06/09 Javascript
jQuery日历插件datepicker用法详解
2016/03/03 Javascript
jquery自定义插件——window的实现【示例代码】
2016/05/06 Javascript
Javascript随机标签云代码实例
2016/06/21 Javascript
Javascript点击按钮随机改变数字与其颜色
2016/09/01 Javascript
详解网站中图片日常使用以及优化手法
2017/01/09 Javascript
使用MUI框架模拟手机端的下拉刷新和上拉加载功能
2017/09/04 Javascript
angularjs中$http异步上传Excel文件方法
2018/02/23 Javascript
Nuxt项目支持eslint+pritter+typescript的实现
2019/05/20 Javascript
详解vue中v-model和v-bind绑定数据的异同
2020/08/10 Javascript
python复制文件的方法实例详解
2015/05/22 Python
python,Django实现的淘宝客登录功能示例
2019/06/12 Python
用ldap作为django后端用户登录验证的实现
2020/12/07 Python
kmart凯马特官网:美国最大的打折零售商和全球最大的批发商之一
2016/11/17 全球购物
财务助理岗位职责
2013/11/10 职场文书
学风建设演讲稿
2014/09/12 职场文书
高中生国庆节演讲稿范文2014
2014/09/21 职场文书
暑假社会实践证明格式
2014/10/28 职场文书
2015年师德师风承诺书
2015/01/22 职场文书
初中生思想道德自我评价
2015/03/09 职场文书
2015小学语文教师个人工作总结
2015/05/20 职场文书
学雷锋感言
2015/08/03 职场文书
2016国庆促销广告语
2016/01/28 职场文书
python 爬取吉首大学网站成绩单
2021/06/02 Python
mybatis 获取无数据的字段不显示的问题
2021/07/15 Java/Android
Nginx配置根据url参数重定向
2022/04/11 Servers
Pytorch中expand()的使用(扩展某个维度)
2022/07/15 Python