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二维切片初始化的实现
Apr 08 Golang
golang正则之命名分组方式
Apr 25 Golang
golang中实现给gif、png、jpeg图片添加文字水印
Apr 26 Golang
解决Golang中goroutine执行速度的问题
May 02 Golang
golang协程池模拟实现群发邮件功能
May 02 Golang
go语言基础 seek光标位置os包的使用
May 09 Golang
golang 实用库gotable的具体使用
Jul 01 Golang
go开发alertmanger实现钉钉报警
Jul 16 Golang
golang生成并解析JSON
Apr 14 Golang
Golang jwt身份认证
Apr 20 Golang
Golang map映射的用法
Apr 22 Golang
Go语言怎么使用变长参数函数
Jul 15 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获取当前日期所在星期(月份)的开始日期与结束日期(实现代码)
2013/06/18 PHP
php使用curl模拟登录后采集页面的例子
2013/11/04 PHP
使用YUI+Ant 实现JS CSS压缩
2014/09/02 PHP
全面解读PHP的Yii框架中的日志功能
2016/03/17 PHP
jquery 表单进行客户端验证demo
2009/08/24 Javascript
图像替换新技术 状态域方法
2010/01/28 Javascript
JQuery 学习笔记01 JQuery初接触
2010/05/06 Javascript
Jquery图形报表插件 jqplot简介及参数详解
2012/10/10 Javascript
jQuery侧边栏随窗口滚动实现方法
2013/03/04 Javascript
extjs两个tbar问题探讨
2013/08/08 Javascript
javascript变量声明实例分析
2015/04/25 Javascript
jquery插件hiAlert实现网页对话框美化
2015/05/03 Javascript
javascript生成不重复的随机数
2015/07/17 Javascript
jQuery插件实现静态HTML验证码校验
2015/11/06 Javascript
清除浏览器缓存的几种方法总结(必看)
2016/12/09 Javascript
Vue 2.0+Vue-router构建一个简单的单页应用(附源码)
2017/03/14 Javascript
React组件之间的通信的实例代码
2017/06/27 Javascript
JS时间控制实现动态效果的实例讲解
2017/07/31 Javascript
Node.js dgram模块实现UDP通信示例代码
2017/09/26 Javascript
javascript函数的节流[throttle]与防抖[debounce]
2017/11/15 Javascript
JS+HTML+CSS实现轮播效果
2017/11/28 Javascript
原生JS实现的自动轮播图功能详解
2018/12/28 Javascript
[02:07]TI9显影之尘系列 - Vici Gaming
2019/08/20 DOTA
pymssql ntext字段调用问题解决方法
2008/12/17 Python
利用python打印出菱形、三角形以及矩形的方法实例
2017/08/08 Python
python多进程控制学习小结
2018/10/31 Python
Tensorflow 模型转换 .pb convert to .lite实例
2020/02/12 Python
python实现手势识别的示例(入门)
2020/04/15 Python
CSS3的Border-radius轻松制作圆角
2012/12/24 HTML / CSS
捷克汽车配件和工具销售网站:TorriaCars
2018/02/26 全球购物
2014年端午节演讲稿范文
2014/05/23 职场文书
物流专业专科生职业生涯规划书
2014/09/14 职场文书
2014物价局民主生活会对照检查材料思想汇报
2014/09/24 职场文书
2014年政府采购工作总结
2014/12/09 职场文书
会计求职简历自我评价
2015/03/10 职场文书
手残删除python之后的补救方法
2021/06/26 Python