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 29 Golang
解决Golang time.Parse和time.Format的时区问题
Apr 29 Golang
golang 实现Location跳转方式
May 02 Golang
go mod 安装依赖 unkown revision问题的解决方案
May 06 Golang
关于golang高并发的实现与注意事项说明
May 08 Golang
golang 实用库gotable的具体使用
Jul 01 Golang
详解Go语言Slice作为函数参数的使用
Jul 02 Golang
golang 语言中错误处理机制
Aug 30 Golang
golang操作rocketmq的示例代码
Apr 06 Golang
Go并发4种方法简明讲解
Apr 06 Golang
Golang 实现 WebSockets 之创建 WebSockets
Apr 24 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采用curl模仿用户登陆新浪微博发微博的方法
2014/11/07 PHP
kindeditor 加入七牛云上传的实例讲解
2017/11/12 PHP
永不消失的title提示代码
2007/02/15 Javascript
Extjs学习笔记之六 面版
2010/01/08 Javascript
Google (Local) Search API的简单使用介绍
2013/11/28 Javascript
jquery easyui使用心得
2014/07/07 Javascript
jQuery控制TR显示隐藏的三种常用方法
2014/08/21 Javascript
JavaScript中判断整数的多种方法总结
2014/11/08 Javascript
详细解读JavaScript的跨浏览器事件处理
2015/08/12 Javascript
JS两个数组比较,删除重复值的巧妙方法(推荐)
2016/06/03 Javascript
CSS3 3D 技术手把手教你玩转
2016/09/02 Javascript
Bootstrap Table表格一直加载(load)不了数据的快速解决方法
2016/09/17 Javascript
js实现文字向上轮播功能
2017/01/13 Javascript
React-router中结合webpack实现按需加载实例
2017/05/25 Javascript
vue 插件的方法代码详解
2019/06/06 Javascript
vue项目创建步骤及路由router
2020/01/14 Javascript
使用Element的InfiniteScroll 无限滚动组件报错的解决
2020/07/27 Javascript
[02:41]2015国际邀请赛中国区预选赛观战指南
2015/05/20 DOTA
[02:36]DOTA2上海特锦赛 回忆电竞生涯的重要瞬间
2016/03/25 DOTA
[01:08:48]LGD vs OG 2018国际邀请赛淘汰赛BO3 第三场 8.25
2018/08/29 DOTA
Python发送Email方法实例
2014/08/21 Python
Python3实现生成随机密码的方法
2014/08/23 Python
Linux下使用python调用top命令获得CPU利用率
2015/03/10 Python
python多进程和多线程究竟谁更快(详解)
2017/05/29 Python
微信小程序跳一跳游戏 python脚本跳一跳刷高分技巧
2018/01/04 Python
Win10下python 2.7.13 安装配置方法图文教程
2018/09/18 Python
Python中顺序表原理与实现方法详解
2019/12/03 Python
Keras loss函数剖析
2020/07/06 Python
地图可视化神器kepler.gl python接口的使用方法
2020/12/22 Python
Clarins娇韵诗英国官网:来自法国的天然护肤品牌
2017/04/18 全球购物
安全大检查实施方案
2014/02/22 职场文书
大学生心理健康活动总结
2015/05/08 职场文书
幼儿园食品安全责任书
2015/05/08 职场文书
人与自然的观后感
2015/06/18 职场文书
eclipse创建项目没有dynamic web的解决方法
2021/06/24 Java/Android
JavaScript 中for/of,for/in 的详细介绍
2021/11/17 Javascript