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:垃圾回收GC触发条件详解
Apr 24 Golang
Go语言使用select{}阻塞main函数介绍
Apr 25 Golang
go语言-在mac下brew升级golang
Apr 25 Golang
go结构体嵌套的切片数组操作
Apr 28 Golang
浅谈Golang 嵌套 interface 的赋值问题
Apr 29 Golang
解决Go gorm踩过的坑
Apr 30 Golang
golang 实用库gotable的具体使用
Jul 01 Golang
Go语言基础map用法及示例详解
Nov 17 Golang
Golang 链表的学习和使用
Apr 19 Golang
详解Go语言中配置文件使用与日志配置
Jun 01 Golang
GoFrame基于性能测试得知grpool使用场景
Jun 21 Golang
Go本地测试解耦任务拆解及沟通详解Go本地测试的思路沟通的重要性总结
Jun 21 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
腾讯QQ php程序员面试题目整理
2010/06/08 PHP
PHP 作用域解析运算符(::)
2010/07/27 PHP
使用PHP备份MySQL和网站发送到邮箱实例代码
2013/11/28 PHP
自己写的php中文截取函数mb_strlen和mb_substr
2015/02/09 PHP
PHP SPL标准库之数据结构堆(SplHeap)简单使用实例
2015/05/12 PHP
PHP简单实现遍历目录下特定文件的方法小结
2017/05/22 PHP
javascript call和apply方法
2008/11/24 Javascript
csdn 博客中实现运行代码功能实现
2009/08/29 Javascript
JavaScript学习笔记之获取当前目录的实现代码
2010/12/14 Javascript
jquery插件lazyload.js延迟加载图片的使用方法
2014/02/19 Javascript
详谈jQuery中的this和$(this)
2014/11/13 Javascript
jQuery弹出层插件Lightbox_me使用指南
2015/04/21 Javascript
jQuery添加和删除输入文本框标签代码
2016/05/20 Javascript
jQuery简单设置文本框回车事件的方法
2016/08/01 Javascript
快速解决brew安装特定版本flow的问题
2018/05/17 Javascript
layer弹出层父子页面事件相互调用方法
2018/08/17 Javascript
webpack中如何使用雪碧图的示例代码
2018/11/11 Javascript
归纳整理Python中的控制流语句的知识点
2015/04/14 Python
Python 备份程序代码实现
2017/03/06 Python
Python入门_浅谈for循环、while循环
2017/05/16 Python
python使用PIL模块获取图片像素点的方法
2019/01/08 Python
python django model联合主键的例子
2019/08/06 Python
利用python实现短信和电话提醒功能的例子
2019/08/08 Python
用HTML5制作一个简单的弹力球游戏
2015/05/12 HTML / CSS
Tea Collection官网:一家位于旧金山的童装公司
2020/08/07 全球购物
旅游与酒店管理的自我评价分享
2013/11/03 职场文书
公司领导推荐信
2013/11/12 职场文书
信用社主任竞聘演讲稿
2014/05/23 职场文书
服装设计专业自荐信
2014/06/17 职场文书
资源环境与城乡规划管理专业自荐书
2014/09/26 职场文书
2014年后备干部工作总结
2014/12/08 职场文书
2015年教师师德师风承诺书
2015/04/28 职场文书
社区敬老月活动总结
2015/05/07 职场文书
傲慢与偏见读书笔记
2015/06/29 职场文书
windows安装python超详细图文教程
2021/05/21 Python
python中数组和列表的简单实例
2022/03/25 Python