GO中的并发编程测试

时间:2013-11-28 18:05:40

标签: testing concurrency go

我正在努力确保我的并发程序没有以下内容,

  • 死锁
  • 活锁
  • 饥饿

我找到了以下工具 http://blog.golang.org/race-detector

我尝试使用启用-race进行编译和运行,但没有看到任何投诉。

有谁知道这是否会检查上述所有问题?在输出中没有收到任何投诉意味着该程序没有这些问题吗?

2 个答案:

答案 0 :(得分:6)

单独测试无法消除死锁,活锁和饥饿,Go竞赛检测器无法检测到它们。 Go程序中的死锁将在运行时被检测到,但通常为时已晚。除非它们也导致死锁,否则不会检测到活锁(非终止繁忙循环)。

线程饥饿与活锁类似,因为应用程序中的不平衡忙碌导致某些活动受阻并且永远不会达到预期的进度。一个例子是彼得·韦尔奇着名的“Wot no Chickens?”。

赛车探测器本身的用途有限,因为某些比赛条件取决于环境,并且在测试阶段可能缺少导致特定比赛的条件,因此比赛探测器将错过它们。

如果所有这些听起来相当暗淡,那么有很多理论工作可以帮助很多。前提是这四个动态问题最好通过设计策略和语言功能来解决,而不是通过测试来解决。举一个简单的例子,Occam编程语言(与其并发模型中的Go非常相似)具有由编译器强制执行的并行使用规则,可消除竞争条件。这对程序员施加了限制:不允许使用可变状态的别名(即指针)。

Go(和Occam)中的线程饥饿同样不应该像Java中那样存在问题,因为并发模型设计得更好。除非你滥用select,否则不会有问题。

死锁最好通过基于理论的设计模式来解决。例如,Martin& Welch发布了A Design Strategy for Deadlock-Free Concurrent Systems,主要描述了客户端 - 服务器策略和i / o-par策略。这是针对奥卡姆计划,但也适用于Go。客户端 - 服务器策略很简单:将Go例程网络描述为一组通信服务器及其客户端;确保网络图中没有循环=>僵局被淘汰了。 I / o-par是形成Go例程的环和环的一种方式,这样就不会在结构中出现死锁。

答案 1 :(得分:2)

恕我直言,比赛探测器从您的列表中检查 nothing 。它检查racy写入内存。 (旁注:运行时检测到Goroutine死锁。)