【问题标题】:Fair Reentrant Lock C++公平可重入锁 C++
【发布时间】:2015-09-12 00:06:55
【问题描述】:

我正在开发一个程序,当一个线程比另一个线程做更多的工作时,它会遭受饥饿。临界区受可重入 QMutex 保护,这是不公平的。

在 Java 中,您可以为锁指定公平参数。 C++(或 boost 库)是否有任何可用的公平可重入锁?最好到 C++11。

我之前做过一些研究,boost中有shared_lock,但我不需要读/写锁。只是一个锁,可以保证每个线程都有平等的机会进入临界区。

非常感谢。

【问题讨论】:

  • 自 C++11 起就有 std::mutexstd::lock_guard<std::mutex>,但不能保证它们是公平的。不过,我相信 MSVC CRT 实现使用等待队列,因此它们在该平台上可能是公平的。
  • 是的..但我需要一个公平的锁...
  • 与其使用在 C++ 中通常不可用的公平参数,您可能会发现您可以通过优先排队工作调度来获得对情况的更多控制,这样您就可以将“繁重”操作节流到避免饥饿。显然,它需要更多的编码,但从长远来看可能会给您带来更好的结果。
  • 从操作系统的角度来看,所有线程都有相似的运行机会,所以如果你没有为你的线程设置不同的优先级并且在某些线程上发生饥饿,这意味着这些线程没有被操作系统线程分配足够的时间调度程序,但是这不会发生。这反映出您的设计可能存在问题

标签: c++ concurrency


【解决方案1】:

C++ 线程原语实际上是基于 Posix 线程,而 Posix 没有任何公平的互斥锁。但是,您的问题表明您的设计存在问题。这里有两个问题:

  1. 可重入互斥锁是问题的征兆。您需要 100% 控制互斥锁的所有权和生命周期。如果您需要可重入互斥锁,则意味着设计是草率的。
  2. 您的描述中的线程不足是由于线程通信设计不当造成的。如果一个线程在工作期间需要一个互斥锁,这意味着,您正在有效地设计一个单线程系统,并且不需要任何线程。

【讨论】:

  • 嗯,是的,原则上,但事情往往没有那么简单;-)
  • @Cameron,原则上不是。在现实生活中。
  • 你可能对可重入是正确的,但你对公平和线程饥饿的看法是不对的。即使在简单的场景中,线程也可能会饿死。做了一个完整的并发课程,广泛讨论了这个问题,现在我在现实中遇到了这个问题。太糟糕了,C++ 对开发多线程程序时真正必不可少的东西的支持很差。
  • @Veaceslav,你能详细说明一下吗?我想看一个例子,其中线程饥饿不是糟糕设计的结果。
  • 一个线程正在为新项目汇集一个队列。在池化时,它会获得一个锁。生产者线程想要在队列中放入一些东西,但消费者线程却被不断池化并获取锁的消费者线程饿死了。这是我用公平锁解决的 Java 作业中的一个。此外,真实案例应用程序:我们具有必须序列化的 sqlite 访问权限。该程序作为一个批处理过程,向数据库写入了很多内容。以及为什么批处理是活跃的,依赖于获取数据的接口功能被饿死了。
猜你喜欢
  • 1970-01-01
  • 2021-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多