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 相关文章推荐
go语言求任意类型切片的长度操作
Apr 26 Golang
golang协程池模拟实现群发邮件功能
May 02 Golang
go select编译期的优化处理逻辑使用场景分析
Jun 28 Golang
K8s部署发布Golang应用程序的实现方法
Jul 16 Golang
go开发alertmanger实现钉钉报警
Jul 16 Golang
Golang 并发下的问题定位及解决方案
Mar 16 Golang
golang为什么要统一错误处理
Apr 03 Golang
golang语言指针操作
Apr 14 Golang
GO语言字符串处理函数之处理Strings包
Apr 14 Golang
Golang 实现WebSockets
Apr 24 Golang
Golang解析JSON对象
Apr 30 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
PHP4和PHP5性能测试和对比 测试代码与环境
2007/08/17 PHP
改变Apache端口等配置修改方法
2008/06/05 PHP
php实现的Captcha验证码类实例
2014/09/22 PHP
CodeIgniter配置之config.php用法实例分析
2016/01/19 PHP
浅析php中array_map和array_walk的使用对比
2016/11/20 PHP
ThinkPHP实现分页功能
2017/04/28 PHP
将HTMLCollection/NodeList/伪数组转换成数组的实现方法
2011/06/20 Javascript
jquery插件制作 自增长输入框实现代码
2012/08/17 jQuery
jquery创建一个ajax关键词数据搜索实现思路
2013/02/26 Javascript
jquery的ajax和getJson跨域获取json数据的实现方法
2014/02/04 Javascript
javascript实现回到顶部特效
2015/05/06 Javascript
JavaScript的Date()方法使用详解
2015/06/09 Javascript
JS实现简单的图书馆享元模式实例
2015/06/30 Javascript
jQuery实现为控件添加水印文字效果(附源码)
2015/12/02 Javascript
在小程序中使用腾讯视频插件播放教程视频的方法
2018/07/10 Javascript
微信小程序按钮去除边框线分享页面功能
2018/08/27 Javascript
详解微信小程序胶囊按钮返回|首页自定义导航栏功能
2019/06/14 Javascript
JS实现transform实现扇子效果
2020/01/17 Javascript
Vue 中 template 有且只能一个 root的原因解析(源码分析)
2020/04/11 Javascript
python实现爬虫下载漫画示例
2014/02/16 Python
Python中最大最小赋值小技巧(分享)
2017/12/23 Python
对pandas读取中文unicode的csv和添加行标题的方法详解
2018/12/12 Python
python requests抓取one推送文字和图片代码实例
2019/11/04 Python
python设置表格边框的具体方法
2020/07/17 Python
Python用SSH连接到网络设备
2021/02/18 Python
html5简介_动力节点Java学院整理
2017/07/07 HTML / CSS
优瑞自动咖啡机官网:Jura
2018/09/29 全球购物
Feelunique德国官方网站:欧洲最大的在线美容零售商
2019/07/20 全球购物
瑞典多品牌连锁店:Johnells
2021/01/13 全球购物
大学生军训自我评价分享
2013/11/09 职场文书
彩色的翅膀教学反思
2014/04/25 职场文书
法院信息化建设方案
2014/05/21 职场文书
公司会议开幕词
2015/01/29 职场文书
劳动模范获奖感言
2015/07/31 职场文书
星际争霸:毕姥爷vs解冻03
2022/04/01 星际争霸
Python实现双向链表基本操作
2022/05/25 Python