我对多线程仍然相当新,但已经多次烧过。 现在我尽量避免一些陷阱,但我很难做到以下几点:
考虑几个线程,线程A
生产者,因此writer
,线程B
,C
,...因此消费者线程reader
。
所有人都共享一个公共缓冲区S
一些基本书籍建议为此场景引入所谓的ReadWriteLock
。
多个并发读取是可能的,但显然只有一个write.Boost也提供了这样的锁,Qt。
让我们假设两个函数f1和f2锁定S进行读取。
在线程B
中调用f1并锁定读取,f1在f1内调用并锁定以便再次读取,因此嵌套锁定是可能的。
现在考虑f1执行的瞬间并首次锁定读取。如果线程A被调用并想要写入,则会被阻止。
此外,如果内部f1 f2被调用并且想要锁定它,因为阻塞的writer
正在等待,在这种情况下,许多锁(例如QReadWriteLock
)也会阻塞readers
。
因此,我们得到了一个非常令人讨厌的死锁,这个死锁是不可预测的,只有当writer
在f1中的锁定和f2的锁定之间发生时才会发生。
我目前避免此类错误的方法是一个调试工具,它跟踪锁定并断言如果同一个线程试图锁定读取两次,但这非常麻烦。 除此之外,我避免将大量代码放入锁中,这有助于我的团队中的其他成员忽略。
可以使用哪些其他功能来预防此类情况? 为什么ReadWriteLocks允许它们呢? 在设计阶段是否有一些通用的经验法则可以避免上述情况?
提前感谢您阅读长篇问题; - )
答案 0 :(得分:0)
也许你可以使用QReadWriteLock中的tryReadLock函数。防止死锁。
如果它无法锁定读取..然后解锁读取的互斥锁。
在某些情况下,它可能会丢失要读取的数据,如果您不想丢失任何要读取的数据,可以通过添加标记或ID号或其他内容来识别您的失败读取作业并将其放入堆栈,所以写完线程完成他的工作后,你将能够恢复你的阅读事情从一个失败的开始。它会使您最大限度地减少损失数据..
我希望它会有所帮助。
我的英语不好。