【阅读总结】Understanding Real-World Concurrency Bugs in Go 小结

最近希望深入一下go 语言细节,在看过基本的语法后,开始找相关经典文章去阅读。虽然阅读总结大部分由GPT生成,但是我认为作为提示词和学习路径,还是有必要记录一下的。

个人总结在此:

以下文章由GPT生成,没有个人思考与总结。


《Understanding Real-World Concurrency Bugs in Go》由Tengfei Tu等人撰写。论文首次对Go语言实际程序中的并发错误进行了系统研究,分析171个并发错误,发现消息传递并不比共享内存更不易出错,某些情况下甚至更容易导致错误,研究结果有助于理解Go语言并发模型,为编写可靠的Go程序和开发调试诊断工具提供指导。

  1. 背景与研究目的:Go语言旨在简化并发编程,但其新的并发原语和机制对并发错误的影响尚不明确。本文通过对6个开源Go应用的研究,分析并发错误的成因、修复方法,比较消息传递和共享内存两种通信机制的易错性,为Go语言并发编程提供指导。
  2. Go语言并发机制与应用
  • 并发单元 - Goroutine:Go使用Goroutine作为并发单元,它是轻量级用户级线程,可通过在函数调用前加go关键字创建,支持匿名函数创建Goroutine,可能引发数据竞争。
  • 同步机制:支持共享内存同步,提供Mutex、RWMutex等原语;Once确保函数只执行一次;WaitGroup用于多个Goroutine完成共享变量访问的同步。还通过通道(chan)实现消息传递,有缓冲和无缓冲通道之分,select语句可用于等待多个通道操作。
  • 研究应用:选取Docker、Kubernetes等6个具有代表性的Go语言应用,这些应用在数据中心环境广泛使用,开发历史长且规模较大。
  1. Go语言并发使用模式
  • Goroutine使用:静态分析显示,6个应用中Goroutine创建频繁,平均每千行代码创建0.18 - 0.83个,多数应用使用匿名函数创建Goroutine更多。动态分析表明,与gRPC - C相比,gRPC - Go在运行时创建更多Goroutine,且Goroutine执行时间更短。
  • 并发原语使用:共享内存同步操作使用频率高于消息传递,Mutex是使用最广泛的原语,消息传递中chan使用频率最高。gRPC - Go使用的并发原语数量和种类均多于gRPC - C,且各应用并发原语使用情况随时间趋于稳定。
  1. 错误研究方法 - 错误收集:通过在GitHub提交历史中搜索并发相关关键词,筛选出3211个匹配提交,随机抽样并人工研究,最终确定171个并发错误。
  • 错误分类:根据错误行为分为阻塞错误(一个或多个Goroutine执行受阻)和非阻塞错误(Goroutine能完成任务但行为不符合预期);根据错误原因分为共享内存错误和消息传递错误。
  • 错误重现:回滚应用版本,构建并运行有错误的程序,依据错误报告中的症状判断是否成功重现错误。
  1. 阻塞错误
  • 根源:约42%由共享内存保护错误导致,如Mutex误用、RWMutex特有的优先级问题、WaitGroup和Cond使用不当;58%由消息传递错误引起,包括通道使用错误、通道与其他阻塞原语配合不当、消息传递库使用错误。
  • 修复:多数共享内存相关错误修复方法与传统语言类似,消息传递相关错误常通过添加消息或关闭操作、添加select语句、更换通道类型等方式修复。错误原因与修复策略、修复使用的原语有较高相关性,修复补丁平均6.8行代码。
  • 检测:Go内置死锁检测器只能检测出2个阻塞错误,因其设计目标为最小化运行时开销,未考虑部分运行中的Goroutine和等待其他系统资源的Goroutine,未来需开发新的检测技术。
  1. 非阻塞错误
  • 根源:约80%由共享内存保护失败引起,包括传统问题和Go新特性导致的问题,如匿名函数使用不当、WaitGroup误用、特殊库使用不当;约20%由消息传递错误引起,如通道误用、特殊库中通道使用不当。
  • 修复:约69%通过限制时间修复,如添加同步原语或移动现有原语;部分通过消除或绕过共享变量访问指令、复制共享变量等方式修复。Mutex和channel是常用的修复原语。
  • 检测:Go数据竞争检测器使用happen - before算法,能检测部分传统错误和匿名函数导致的错误,但因非阻塞错误类型多样、算法依赖Goroutine交错执行、存储历史信息有限等原因,无法检测所有非阻塞错误。
  1. 讨论与展望:消息传递不一定比共享内存更不易出错,它是阻塞错误的主要原因,且与其他机制结合时难以检测。研究揭示的错误代码模式可用于并发错误检测,未来应结合静态和动态技术开发更有效的检测工具。
  2. 结论:首次全面实证研究Go语言并发错误,发现消息传递和共享内存都可能导致并发错误,期望研究能加深对Go并发错误的理解,引起更多关注。
相关推荐
大胖丫10 分钟前
vue 学习-vite api.js
开发语言·前端·javascript
遇见很ok12 分钟前
js中 ES6 新特性详解
开发语言·javascript·es6
没有晚不了安20 分钟前
1.13作业
开发语言·python
布谷歌24 分钟前
Oops! 更改field的数据类型,影响到rabbitmq消费了...(有关于Java序列化)
java·开发语言·分布式·rabbitmq·java-rabbitmq
被程序耽误的胡先生29 分钟前
java中 kafka简单应用
java·开发语言·kafka
刀客12330 分钟前
python小项目编程-中级(1、图像处理)
开发语言·图像处理·python
Long_poem33 分钟前
【自学笔记】Spring Boot框架技术基础知识点总览-持续更新
spring boot·笔记·后端
卷卷的小趴菜学编程34 分钟前
c++之多态
c语言·开发语言·c++·面试·visual studio code
冷琴19961 小时前
基于Python+Vue开发的反诈视频宣传管理系统源代码
开发语言·vue.js·python
楠枬1 小时前
网页五子棋——对战后端
java·开发语言·spring boot·websocket·spring