何时使用C++11的mutex、lock、unique_lock、shared_lock等?

20
  1. 除了shared_lock的析构函数会解开关联的互斥锁之外,shared_lockshared_mutex.lock_shared()之间有什么区别?
  2. shared_lock是唯一可以与之配合使用的互斥锁类吗?
  3. 为什么有人想要使用lock_guard而不是unique_lock
  4. 如果我有许多线程在不断地锁定一个变量进行读取(shared_lock),而我有一个变量在尝试用unique_lock进行写入锁定,那么这个写入线程是否会优先于其他线程进行操作?
  5. 对于问题#4,是否有可能发生死锁?

2
始终优先选择RAII而非显式释放操作。否则,使用提供所需功能的最简单方法,这样您就不必为不需要的内容付费。 - David Schwartz
通过RAII,你的意思是用大括号将我的锁定代码包含起来吗?例如: { lock; foo = ...; // 析构函数将解锁 } - Benoît Dubreuil
1
不和是非常重要的。锁类满足RAII的要求,即在锁定某些内容后自动解锁一次锁的析构函数被调用。使用互斥锁时,必须显式地解锁它们。 - Nimelrian
3
《C++并发编程实战》(Anthony Williams著)是一个不错的起点。 - Ivan Aksamentov - Drop
在互斥锁页面上,示例现在使用lock_guard。 - Cubbi
谢谢大家,我想我终于理解了RAII习语(至少是基础知识),但仍有一些问题我找不到答案。 - Benoît Dubreuil
1个回答

9
  1. shared_mutex.lock_shared()是一个函数调用,它以共享模式锁定shared_mutex,而shared_lock是一个“锁类”,用于在作用域结束时锁定和自动解锁互斥量。

  2. 不,您可以使用任何符合SharedMutex要求的类型来使用shared_lock

  3. 除非需要unique_lock的其他功能,否则始终使用lock_guard。这样你的意图更清晰。

  4. 这与shared_lockunique_lock无关,而与您正在使用的SharedMutex有关。确切的行为未由标准指定。但是以下是一些线索:

    • 在Windows上,shared_lock通常使用SRWLOCK实现,并尝试公平地平衡读者和写者。没有人会在这里拥有更高的优先级。
    • 在POSIX系统上,shared_mutex很可能是基于pthread_rwlock_t实现的,实现通常会优先考虑读者,因为它要求支持递归读锁。
    • Boost shared_mutex尝试公平对待,不偏向任何一方。
  5. 对于偏向读者的shared_mutex,如果始终至少有一个读者持有锁,则您的编写器线程可能永远无法获取锁定。


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