2 回答
TA贡献1852条经验 获得超1个赞
仅靠测试无法消除死锁、活锁和饥饿,并且 Go 竞赛检测器无法检测到它们。Go 程序中的死锁将在运行时检测到,但通常为时已晚。活锁(非终止忙循环)不会被检测到,除非它们也导致死锁。
线程饥饿类似于活锁,因为应用程序中的不平衡忙碌会导致某些活动受阻并且永远不会取得预期的进展。一个例子是著名的“没有鸡吗?'彼得韦尔奇。
竞态检测器本身的用途有限,因为某些竞态条件取决于环境,并且在测试阶段可能不存在导致特定竞态的条件,因此竞态检测器会错过它们。
如果所有这些听起来都相当黯淡,那么有大量理论工作可以提供很大帮助。前提是这四个动态问题最好通过设计策略和语言特性来解决,而不是通过测试。作为一个简单的例子,Occam 编程语言(在并发模型中很像 Go)有一个由编译器强制执行的并行使用规则,可以消除竞争条件。这对程序员施加了限制:不允许使用可变状态的别名(即指针)。
Go(和 Occam)中的线程饥饿也不应该像 Java 中那样是一个问题,因为并发模型设计得更好。除非你滥用select
,否则不会有问题。
死锁最好通过基于理论的设计模式来解决。例如,Martin & Welch 发表了A Design Strategy for Deadlock-Free Concurrent Systems,主要描述了客户端-服务器策略和 i/o-par 策略。这是针对 Occam 程序的,但也适用于围棋。客户端-服务器策略很简单:将您的 Go 例程网络描述为一组通信服务器及其客户端;确保网络图中没有循环 => 消除了死锁。I/o-par 是一种形成 Go 例程的环和环的方法,这样结构内就不会出现死锁。
- 2 回答
- 0 关注
- 280 浏览
添加回答
举报