GO中的并发编程测试

nis*_*013 3 testing concurrency go

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

  • 僵局
  • 活锁
  • 饥饿

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

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

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

Ric*_*777 6

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

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

竞赛检测器本身的实用性受到限制,因为某些竞赛条件取决于环境,并且在测试阶段可能缺少导致特定竞赛的条件,因此竞赛检测器将错过它们.

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

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

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