fna*_*nig 6 c++ multithreading synchronization
对于我的项目,我需要一个完全递归的多读者/单作者锁(共享互斥锁) - 我不同意这样的观点:如果你有完全的const-correctness,你不应该需要它们(有一些讨论关于在boost邮件列表中,在我的情况下,锁应该保护一个完全透明的缓存,这在任何情况下都是可变的.
至于递归MRSW锁的语义,我认为唯一有意义的是除了共享锁之外获取一个独占锁暂时释放共享锁,当独占锁被释放时重新获取.
有一些奇怪的效果,解锁可以等待,但我可以忍受 - 无论如何写很少发生和递归锁定通常只通过递归代码路径发生,在这种情况下,调用者必须准备好调用可能在任何情况下等待.为了避免这种情况,人们仍然可以简单地升级锁而不是使用递归锁定.
在独占锁上获取共享锁显然只会增加锁定数.
所以问题就变成了 - 我应该如何实现呢?关键部分和两个信号量的常用方法在这里不起作用,因为 - 据我所知 - 唤醒线程必须通过将其线程ID插入锁的所有者映射来进行握手.
我认为它可以使用两个条件变量和几个互斥量,但是最终会使用大量的同步原语听起来有点像我的口味.
我想到的一个想法是利用TLS记住我所持有的锁类型(可能还有本地锁定计数).不得不考虑一下 - 但我现在仍然会发布这个问题.
目标平台是Win32但这应该不重要.请注意,我专门针对Win2k,因此与Windows 7中新的MRSW锁原语相关的任何内容都与我无关.:-)
嗯,我做了一些思考。从简单的“两个信号量和一个临界区”开始,向结构中添加写入器锁定计数和所属写入器 TID。
解锁仍然在 critsec 中设置大部分新状态。读取器通常仍然会增加锁定计数 - 递归锁定只是将不存在的读取器添加到计数器。
在 writers lock() 期间,我会比较拥有的 TID,如果写入者已经拥有它,则写入锁定计数器会增加。
设置新的写入器 TID 不能通过解锁()来完成 - 它不知道哪一个将被唤醒,但是如果写入器在其解锁()中将其重置为零,那么这不是问题 - 当前线程 ID 获胜永远不会为零并且设置它是一个原子操作。
一切听起来都很简单 - 还剩下一个棘手的问题:当写入者等待时,递归的读取器-读取器锁将导致死锁。而且我不知道如何解决读取器偏向锁的问题...不知何故,我需要知道我是否已经拥有读取器锁。
在我意识到可用插槽的数量可能相当有限之后,使用 TLS 听起来不太好......