multithreading - 如何推理互斥体组合的正确性?
问题描述
我正在尝试使用互斥锁实现信号量,以了解有关并发原语和模式的更多信息,以及如何编写正确的并发程序。
这是我找到的资源: http ://webhome.csc.uvic.ca/~mcheng/460/notes/gensem.pdf
解决方案 #1 在第 9 页被标记为“不正确”。我在这里实现了算法。多次运行此程序可能会导致线程冻结。我做了一些分析并意识到d
可能会发生以下对互斥锁的操作序列:
// d was initialized as locked
d.unlock(); // d is unlocked
d.unlock(); // d is still unlocked (unaffected)
d.lock(); // d is locked
d.lock(); // d is still locked (deadlock)
这将导致最后一个d.lock()
死锁。
解决方案 #2 通过重用 mutex 来保护从信号线程到唤醒线程的转换,从而解决了这个问题m
。我在这里实现了这个版本。
在这个解决方案中, after d.unlock()
,m
保持锁定状态,这意味着后续
post()
操作将被阻止,直到m
被解锁。然后d.lock()
调用 following m.unlock()
,确保在允许后续操作运行d
之前处于锁定状态。post()
尽管我了解此解决方案如何解决该问题,但我很难就其他潜在问题证明其正确性。有没有我们可以遵循的一般规则和指导方针来确保、争论甚至证明这样的程序的正确性?
我想问这个问题是因为注释中的下两个解决方案。我实现了解决方案 #3和解决方案 #4,但是在多次测试时,两者都有冻结的线程。我不确定这是我的实施问题还是解决方案本身不正确。
如果您能分析这些解决方案的正确性,我将不胜感激,但我比以往任何时候都更想学习一种方法来推理任何此类算法并验证它们的正确性。
解决方案
推荐阅读
- python - python中的方程和数学
- video - 使用 ffmpeg 生成单个 MPEG-Dash 片段
- oracle - 如何在 Oracle 12.1.0.2 中优化此查询?
- java - 不将工具栏连接到导航抽屉怎么办?
- indentation - 如何使用jspdf缩进多行段落的第一行
- c++ - 为 Visual Studio 代码下载 C++ 扩展时出错
- vector - 在地图中按键删除特定条目。std::unordered_map
> 议员; - regex - 从查询中获取所有分组字段
- python - 生成器内存使用与循环内存使用
- reactjs - React 的 `memo` 在返回的函数中删除泛型