这是一个面试问题。你如何实现读/写互斥?将有多个线程读取和写入资源。我不知道该怎么做。如果需要任何信息,请告诉我。
更新:我不确定我上面的陈述是否有效/可理解。但我真正想知道的是,如何根据互斥锁和其他所需的同步对象在单个对象上实现多次读取和多次写入?
答案 0 :(得分:13)
Dekker的算法是第一个已知的算法 正确的解决方案 并发中的排除问题 节目。解决方案是 归功于荷兰数学家Th。 Edsger W. Dijkstra的J. Dekker在他的作品中 关于合作顺序的手稿 流程。它允许两个线程 在没有的情况下共享一次性资源 冲突,仅使用共享内存 通信。
请注意,Dekker的算法使用spinlock(非busy waiting)技术。
(Th.J. Dekker的解决方案,由E. W. Dijkstra在他的EWD1303 paper中提到)
答案 1 :(得分:1)
简短的回答是,令人惊讶难以推出自己的读/写锁。很容易错过一个可能导致死锁的非常微妙的计时问题,两个线程都认为它们具有“独占”锁等等。
简而言之,您需要记住在任何特定时间有多少读者活跃。仅当活动读取器的数量为零时,才应授予线程写入访问权限。关于读者或作者是否优先考虑,有一些设计选择。 (通常,你希望给作者提供优先权,假设写作不那么频繁。)(令人惊讶的)棘手的部分是确保没有作者在有读者时被授予访问权限,反之亦然。
有一篇优秀的MSDN文章"Compound Win32 Synchronization Objects",它将指导您创建读取器/写入器锁。它开始很简单,然后变得越来越复杂,以处理所有角落案件。突出的一点是,他们展示了一个看起来非常好的样本 - 然后他们会解释为什么它实际上不起作用。如果他们没有指出问题,你可能从未注意到。非常值得一读。
希望这有用。
答案 2 :(得分:0)
这对于面试来说听起来像是一个相当困难的问题;我不会“实现”读/写互斥,从一开始就写一个 - 有更好的现成解决方案可用。明智的现实世界是使用现有的互斥体类型。也许他们真正想知道的是你如何使用这种类型?
答案 3 :(得分:0)
Afaik您需要原子比较和交换指令,或者您需要能够禁用中断。请参阅维基百科上的Compare-and-swap。至少,这就是操作系统如何实现它。如果您有操作系统,请站在它的肩膀上,并使用现有的库(例如boost)。