C++中的读写互斥锁

6
这是一个面试问题。如何实现读写互斥锁?会有多个线程读取和写入资源。我不确定该如何处理。如果需要任何信息,请告诉我。
更新:我不确定我上面的陈述是否有效/可理解。但我真正想知道的是,如何在互斥锁和其他所需同步对象方面实现对单个对象的多次读取和多次写入。

你是在谈论普通的互斥锁还是使用互斥锁/信号量/条件变量实现的多读单写互斥锁? - stefaanv
@stefaanv:我不确定,但我认为这是使用互斥/信号量/条件变量实现的多重读取/多重写入互斥锁。是否有这样的事物/方式? - jasonline
你如何使用什么来实现特定的互斥锁?你需要一些基本的同步能力,而我怀疑所有平台的基本原理都是相同的。至少需要添加一个平台标签。 - David Thornley
这个答案展示了如何使用Boost实现MRSW互斥锁:https://dev59.com/uXNA5IYBdhLWcg3wX8nk#989816 - stefaanv
@stefaanv:如果我的术语不正确,请见谅。如何在互斥锁和其他所需的同步对象方面实现单个对象上的多次读取和多次写入?我已更新我的问题。 - jasonline
显示剩余2条评论
4个回答

13

请查看德克尔算法

德克尔算法是并发编程中互斥问题的第一个已知正确解决方案。该解决方案归功于荷兰数学家Th.J.Dekker,由Edsger W. Dijkstra在他的合作顺序进程手稿中提出。它允许两个线程共享单一的资源而不会发生冲突,仅使用共享内存进行通信。

请注意,Dekker算法使用自旋锁(而不是忙等待)技术。
(Th.J.Dekker的解决方案,由E.W.Dijkstra在他的EWD1303 paper中提到) alt text


1
我喜欢你只回答了问题,而不是深入操作系统的细节 :) - Matt Joiner

1

简而言之,自己编写读/写锁是非常困难的,这可能会导致死锁、两个线程都认为它们拥有“独占”锁等非常微妙的时间问题。

简单来说,您需要在任何特定时间内保持活动读者的计数。只有当活动读者数量为零时,才应授予线程写入访问权限。关于读者或写者谁优先的设计选择有一些选择。(通常,您希望给写者优先权,因为写入不太频繁。)(令人惊讶的)棘手部分是确保没有读者时给予写者访问权限,反之亦然。

有一篇出色的MSDN文章"Compound Win32 Synchronization Objects", 它带您了解如何创建读/写锁。它从简单开始,然后变得更加复杂以处理所有边角情况。其中一个突出的事情是,他们展示了一个看起来完全正常的样本,然后他们会解释为什么它实际上不起作用。如果他们没有指出问题,您可能永远不会注意到。非常值得一读。

希望这有所帮助。


0

这似乎是一道相当困难的面试问题;我不会“实现”读/写互斥锁,也就是从头开始编写一个--有更好的现成解决方案可用。明智的现实做法是使用现有的互斥锁类型。也许他们真正想知道的是你如何使用这样的类型?


ShellShock:读/写互斥锁不能通过常规互斥锁和信号量来实现吗?我不熟悉信号量,但我感觉面试官是在引导我找到这个解决方案。 - jasonline
1
你能推荐任何现成解决方案的示例吗? - jasonline

0
据我所知,您需要使用原子比较和交换指令,或者需要能够禁用中断。请参见维基百科上的比较和交换。至少,这是操作系统实现它的方式。如果您有一个操作系统,请站在它的肩膀上,并使用现有库(例如boost)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接