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 相关文章推荐
goland 清除所有的默认设置操作
Apr 28 Golang
golang json数组拼接的实例
Apr 28 Golang
基于Go Int转string几种方式性能测试
Apr 28 Golang
Go使用协程交替打印字符
Apr 29 Golang
Golang实现AES对称加密的过程详解
May 20 Golang
Golang标准库syscall详解(什么是系统调用)
May 25 Golang
一文搞懂Golang 时间和日期相关函数
Dec 06 Golang
victoriaMetrics库布隆过滤器初始化及使用详解
Apr 05 Golang
golang用type-switch判断interface的实际存储类型
Apr 14 Golang
GO语言字符串处理函数之处理Strings包
Apr 14 Golang
Golang入门之计时器
May 04 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分页显示制作详细讲解
2008/11/19 PHP
解析php下载远程图片函数 可伪造来路
2013/06/25 PHP
fsockopen pfsockopen函数被禁用,SMTP发送邮件不正常的解决方法
2015/09/20 PHP
PHP实现判断数组是一维、二维或几维的方法
2017/02/06 PHP
Laravel框架运行出错提示RuntimeException No application encryption key has been specified.解决方法
2019/04/02 PHP
PHP实现随机发扑克牌
2020/04/22 PHP
Mozilla 表达式 __noSuchMethod__
2009/04/05 Javascript
推荐11款jQuery开发的复选框和单选框美化插件
2011/08/02 Javascript
Js实现双击鼠标自动滚动屏幕的示例代码
2013/12/14 Javascript
window.open 以post方式传递参数示例代码
2014/02/27 Javascript
深入分析js的冒泡事件
2014/12/05 Javascript
node.js中使用socket.io制作命名空间
2014/12/15 Javascript
用原生JS对AJAX做简单封装的实例代码
2016/07/13 Javascript
JS 调试中常见的报错问题解决方法
2017/05/20 Javascript
详解JavaScript中的六种错误类型
2017/09/21 Javascript
Vue项目中使用Vux的安装过程
2018/05/01 Javascript
微信小程序学习笔记之函数定义、页面渲染图文详解
2019/03/28 Javascript
JavaScript的console命令使用实例
2019/12/03 Javascript
JavaScript 实现自己的安卓手机自动化工具脚本(推荐)
2020/05/13 Javascript
[58:54]EG vs RNG 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/18 DOTA
python中使用urllib2伪造HTTP报头的2个方法
2014/07/07 Python
Python实现获取操作系统版本信息方法
2015/04/08 Python
python魔法方法-属性转换和类的表示详解
2016/07/22 Python
浅谈用Python实现一个大数据搜索引擎
2017/11/28 Python
Python自动化运维之Ansible定义主机与组规则操作详解
2019/06/13 Python
详解Python中如何将数据存储为json格式的文件
2020/11/18 Python
简单说说tomcat的配置
2013/05/28 面试题
《猫》教学反思
2014/02/26 职场文书
贯彻学习两会心得体会范文
2014/03/17 职场文书
法学专业求职信
2014/07/15 职场文书
国家税务局干部作风整顿整改措施
2014/09/18 职场文书
授权委托书(法人单位用)
2014/09/29 职场文书
老人节标语大全
2014/10/08 职场文书
安全员岗位职责范本
2015/04/11 职场文书
2015婚礼主持词开场白
2015/05/28 职场文书
instantclient客户端 连接oracle数据库
2022/04/26 Oracle