go goroutine 怎样更好的进行错误处理
2021/7/10 23:11:45
本文主要是介绍go goroutine 怎样更好的进行错误处理,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
前言
在 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 怎样更好的进行错误处理的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-20go-zero 框架的 RPC 服务 启动start和停止 底层是怎么实现的?-icode9专业技术文章分享
- 2024-12-19Go-Zero 框架的 RPC 服务启动和停止的基本机制和过程是怎么实现的?-icode9专业技术文章分享
- 2024-12-18怎么在golang中使用gRPC测试mock数据?-icode9专业技术文章分享
- 2024-12-15掌握PageRank算法核心!你离Google优化高手只差一步!
- 2024-12-15GORM 中的标签 gorm:"index"是什么?-icode9专业技术文章分享
- 2024-12-11怎么在 Go 语言中获取 Open vSwitch (OVS) 的桥接信息(Bridge)?-icode9专业技术文章分享
- 2024-12-11怎么用Go 语言的库来与 Open vSwitch 进行交互?-icode9专业技术文章分享
- 2024-12-11怎么在 go-zero 项目中发送阿里云短信?-icode9专业技术文章分享
- 2024-12-11怎么使用阿里云 Go SDK (alibaba-cloud-sdk-go) 发送短信?-icode9专业技术文章分享
- 2024-12-10搭建个人博客网站之一、使用hugo创建个人博客网站