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 相关文章推荐
golang在GRPC中设置client的超时时间
Apr 27 Golang
golang 如何通过反射创建新对象
Apr 28 Golang
golang 在windows中设置环境变量的操作
Apr 29 Golang
Golang 获取文件md5校验的方法以及效率对比
May 08 Golang
go语言基础 seek光标位置os包的使用
May 09 Golang
Golang中异常处理机制详解
Jun 08 Golang
go web 预防跨站脚本的实现方式
Jun 11 Golang
Go语言设计模式之结构型模式
Jun 22 Golang
golang 实用库gotable的具体使用
Jul 01 Golang
深入理解go slice结构
Sep 15 Golang
golang为什么要统一错误处理
Apr 03 Golang
Golang 字符串的常见操作
Apr 19 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
在PHP的图形函数中显示汉字
2006/10/09 PHP
php下把数组保存为文件格式的实例应用
2010/02/08 PHP
Yii入门教程之Yii安装及hello world
2014/11/25 PHP
php微信公众号开发之秒杀
2018/10/20 PHP
iframe 异步加载技术及性能分析
2011/07/19 Javascript
javascript代码编写需要注意的7个小细节小结
2011/09/21 Javascript
json2.js的初步学习与了解
2011/10/06 Javascript
关于jquery ajax 调用带参数的webservice返回XML数据一个小细节
2012/07/31 Javascript
JS+CSS实现的拖动分页效果实例
2015/05/11 Javascript
JQuery异步加载PartialView的方法
2016/06/07 Javascript
JavaScript 对象详细整理总结
2016/09/29 Javascript
Angular.js实现多个checkbox只能选择一个的方法示例
2017/02/24 Javascript
angular2 组件之间通过service互相传递的实例
2018/09/30 Javascript
微信小程序实现登录遮罩效果
2018/11/01 Javascript
解决VUE-Router 同一页面第二次进入不刷新的问题
2020/07/22 Javascript
[01:04:39]OG vs Mineski 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
matplotlib绘制动画代码示例
2018/01/02 Python
pandas数值计算与排序方法
2018/04/12 Python
python获取本机所有IP地址的方法
2018/12/26 Python
OpenCV图像颜色反转算法详解
2019/05/13 Python
pytorch中nn.Conv1d的用法详解
2019/12/31 Python
一些常用的HTML5模式(pattern) 总结
2015/07/14 HTML / CSS
顶丰TOPPIK台湾官网:增发纤维假发,告别秃发困扰
2018/06/13 全球购物
Bandier官网:奢侈、时尚前卫的健身服装首选目的地
2020/07/05 全球购物
什么是TCP/IP
2014/07/27 面试题
应聘教师自荐信
2013/10/12 职场文书
高中生毕业学习总结的自我评价
2013/11/14 职场文书
厨房工作人员岗位职责
2013/11/15 职场文书
护理专科毕业自荐信范文
2014/04/21 职场文书
蓬莱阁导游词
2015/02/04 职场文书
校运会新闻稿
2015/07/17 职场文书
2016消防宣传标语口号
2015/12/26 职场文书
让人感觉高大上的讲话稿怎么写?
2019/07/08 职场文书
聊聊redis-dump工具安装问题
2022/01/18 Redis
CSS实现渐变色边框(Gradient borders)的5种方法
2022/03/25 HTML / CSS
ipad隐藏软件app图标方法
2022/04/19 数码科技