从 bug 中学习:六大开源项目告诉你 go 并发编程的那些坑.docx
《从 bug 中学习:六大开源项目告诉你 go 并发编程的那些坑.docx》由会员分享,可在线阅读,更多相关《从 bug 中学习:六大开源项目告诉你 go 并发编程的那些坑.docx(8页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、从bug中学习:六大开源项目告诉你go并发编程的那些坑richardyao腾讯CSIG后台开发工程师并发编程中go不仅仅支持传统的通过分享内存的方式来通信更推崇通过channel来传递消息这种新的并发编程模型会出现不同于以往的bug。从bug中学习?UnderstandingReal-WorldConcurrencyBugsinGo?这篇paper在分析了六大开源工程并发相关的bug之后为我们总结了go并发编程中常见的坑。别往坑里跳编程更美妙。在go中创立goroutine非常简单在函数调用前加go关键字这个函数的调用就在一个单独的goroutine中执行了go支持匿名函数让创立gorouti
2、ne的操作更加简洁。另外在并发编程模型上go不仅仅支持传统的通过分享内存的方式来通信更推崇通过channel来传递消息Donotcommunicatebysharingmemory;instead,sharememorybycommunicating.这种新的并发编程模型会带来新类型的bug从bug中学习?UnderstandingReal-WorldConcurrencyBugsinGo?这篇paper在Docker、Kubernetes、etcd、gRPC、CockroachDB、BoltDB六大开源工程的commitlog中搜索等关键字race、deadlock、synchronizat
3、ion、concurrency、lock、mutex、atomic、compete、context、once、goroutineleak找出这六大工程中并发相关的bug然后归类这些bug总结出了go并发编程中常见的一些坑。通过学习这些坑可以让我们在以后的工程里防范类似的错误或遇到类似问题的时候可以帮助指导快速定位排查。unbufferedchannel由于receiver退出导致sender侧block如下面一个bug的例子funcfinishReq(timeouttime.Duration)obch:make(chanob)gofunc()result:fn()ch-result/block
4、()selectcaseresult-ch:returnresultcase-time.After(timeout):returnnil本意是想调用fn()时加上超时的功能假如fn()在超时时间没有返回那么返回nil。但是当超时发生的时候针对代码中第二行创立的ch来讲由于已经没有receiver了第5行将会被block住导致这个goroutine永远不会退出。Ifthecapacityiszeroorabsent,thechannelisunbufferedandcommunicationsucceedsonlywhenbothasenderandreceiverareready.Otherw
5、ise,thechannelisbufferedandcommunicationsucceedswithoutblockingifthebufferisnotfull(sends)ornotempty(receives).这个bug的修复方式也是非常的简单把unbufferedchannel修改成bufferedchannel。funcfinishReq(timeouttime.Duration)obch:make(chanob,1)gofunc()result:fn()ch-result/block()selectcaseresult-ch:returnresultcase-time.Aft
6、er(timeout):returnnil考虑在上面的例子中固然这样不会block了但是channel一直没有被关闭channel保持不关闭是否会导致资源的泄漏呢WaitGroup误用导致阻塞下面是一个WaitGroup误用导致阻塞的一个bug的例子s:/github/moby/moby/pull/25384vargroupsync.WaitGroupgroup.Add(len(pm.plugins)for_,p:rangepm.pluginsgofunc(p*plugin)defergroup.Done()(p)group.Wait()当len(pm.plugins)大于等于2时第7行将会被
7、卡住因为这个时候只启动了一个异步的goroutinegroup.Done()只会被调用一次group.Wait()将会永久阻塞。修复如下vargroupsync.WaitGroupgroup.Add(len(pm.plugins)for_,p:rangepm.pluginsgofunc(p*plugin)defergroup.Done()(p)group.Wait()context误用导致资源泄漏如下面的代码所示hctx,hcancel:context.WithCancel(ctx)iftimeout0hctx,hcancelcontext.WithTimeout(ctx,timeout)第一
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- bug 中学习:六大开源项目告诉你 go 并发编程的那些坑 学习 六大 项目 告诉 并发 编程 那些
限制150内