英文:
Concurrent programming test in GO
问题
我正在尝试确保我的并发程序不会出现以下问题:
- 死锁(deadlock)
- 活锁(livelock)
- 饥饿(starvation)
我找到了下面这个工具:
http://blog.golang.org/race-detector
我尝试使用启用了-race
选项的编译和运行,并没有看到任何警告。
有人知道这个工具是否检查了所有上述问题吗?在输出中没有收到任何警告是否意味着程序没有这些问题?
英文:
I'm trying to ensure that my concurrent program is free of the following,
- deadlock
- livelock
- starvation
I found the following tool
http://blog.golang.org/race-detector
And I tried compiling and running using -race
enabled and did not see any complaints.
Does anyone know whether this checks for all the above issues? Does not receiving any complaints in the output mean to say that the program is free of these issues?
答案1
得分: 6
死锁、活锁和饥饿问题不能仅通过测试来消除,而且它们无法被Go竞争检测器检测到。Go程序中的死锁将在运行时被检测到,但通常为时已晚。除非活锁(非终止的忙碌循环)也导致死锁,否则它们将不会被检测到。
线程饥饿问题类似于活锁,因为应用程序中的不平衡繁忙导致某些活动受阻,无法取得预期的进展。一个例子是Peter Welch的著名作品“Wot no Chickens?”。
竞争检测器本身的实用性有限,因为某些竞争条件取决于环境和导致特定竞争的条件可能在测试阶段不存在,因此竞争检测器会忽略它们。
如果这些听起来相当令人沮丧,那么有一些理论工作可以提供很大帮助。前提是,这四个动态问题最好通过设计策略和语言特性来解决,而不是通过测试。一个简单的例子是Occam编程语言(在并发模型上与Go非常相似),它具有由编译器强制执行的并行使用规则,可以消除竞争条件。这对程序员施加了限制:不允许对可变状态(即指针)进行别名。
在Go(和Occam)中,线程饥饿问题也不应该像在Java中那样成为一个问题,因为并发模型设计得更好。除非滥用select
语句,否则不会出现问题。
死锁最好通过基于理论的设计模式来解决。例如,Martin和Welch发表了一篇名为“无死锁并发系统的设计策略”的论文,主要描述了客户端-服务器策略和i/o-par策略。这适用于Occam程序,也适用于Go。客户端-服务器策略很简单:将Go协程网络描述为一组通信的服务器和客户端;确保网络图中没有循环=>死锁被消除。i/o-par是一种形成Go协程环和环面的方法,以确保结构内部不会发生死锁。
英文:
Deadlock, livelock and starvation cannot be eliminated by testing alone and they are not detected by the Go race detector. Deadlocks in Go programs will be detected at runtime, but then it's usually too late. Livelocks (non-terminating busy loops) will not be detected unless they also cause a deadlock.
Thread starvation is similar to livelock in that imbalanced busy-ness in an application causes some activities to be stymied and never make the expected progress. An example is the famous 'Wot no Chickens?' by Peter Welch.
The race detector itself is limited in its usefulness because some race conditions depend on environment and the conditions that cause a particular race may be absent during the testing phase, so the race detector will miss them.
If all this sounds rather bleak, there is a body of theoretical work that can help a lot. The premise is that these four dynamic problems are best addressed via design strategies and language features, rather than by testing. As a simple example, the Occam programming language (which is quite like Go in its concurrency model) has a parallel usage rule enforced by the compiler that eliminates race conditions. This imposes a restriction on the programmer: aliases for mutable state (i.e. pointers) are not allowed.
Thread starvation in Go (and Occam) should likewise not be as much a problem as in Java because the concurrency model is better designed. Unless you abuse select
, it won't be a problem.
Deadlock is best addressed by theoretically-based design patterns. For example, Martin & Welch published A Design Strategy for Deadlock-Free Concurrent Systems, which described principally the client-server strategy and the i/o-par strategy. This is aimed at Occam programs but applies to Go as well. The client-server strategy is simple: describe your Go-routine network as a set of communicating servers and their clients; ensure that there are no loops in the network graph => deadlock is eliminated. I/o-par is a way to form rings and toruses of Go-routines such that there will not be a deadlock within the structure.
答案2
得分: 2
在我个人看来,竞争检测器不会检查你的列表中的任何内容。它只会检查对内存的并发写操作。(顺便说一下:Go协程死锁是由运行时检测到的。)
英文:
IMHO the race detector checks nothing from your list. It checks racy writes to memory. (Sidenote: Goroutine deadlocks are detected by the runtime.)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论