互斥锁的发生顺序是不是与询问的顺序相同?

Posted

技术标签:

【中文标题】互斥锁的发生顺序是不是与询问的顺序相同?【英文标题】:Do mutex locks happen in the same order they are asked?互斥锁的发生顺序是否与询问的顺序相同? 【发布时间】:2012-01-28 16:17:30 【问题描述】:

我目前正在尝试使用std::thread 创建一个非常简单的线程池。 为了在给定任务完成后保持线程“活动”,我将std::mutex 与每个线程关联起来。

原理有点像这样:

// Thread loop
while (1)

  m_oMutex->lock();
  m_oMutex->unlock();
  m_bAvailable = false;
  m_oTask();
  m_bAvailable = true;


// ThreadPool function which gives a task to a thread
void  runTask(boost::function<void ()> oTask)

  [...]
  m_oThreads[i]->setTask(oTask);
  m_oMutexes[i]->unlock(); // same mutex as thread's m_oMutex
  m_oMutexes[i]->lock();

要查找iThreadPool 会搜索将m_bAvailable 设置为true 的线程对象。它解锁相应的互斥体,以便thread 可以锁定它并执行它的任务。 thread 立即将其解锁,因此 ThreadPool 可以再次锁定它,因此一旦完成任务,thread 就会停止。

但问题是,锁会按照线程要求的顺序进行吗?换句话说,如果threadmutex 进行了锁定,那么ThreadPool 将其解锁并再次锁定它,我确定锁定将首先给予thread 吗?如果没有,有办法保证吗?

【问题讨论】:

【参考方案1】:

不,您不能保证您的线程循环将按原样获取您的示例中的锁。使用条件变量向线程循环发出信号,表明它应该唤醒并获取锁。见std::condition_variable::wait(...)。 condition-variable

更多关于这个话题的一般信息可以在这里找到http://en.wikipedia.org/wiki/Condition_variable。如果您使用的是 pthread 库,则等效调用将是“线程循环”中的 pthread_cond_wait 和 runTask 函数中的 pthread_cond_signal

【讨论】:

谢谢。 condition_variable 似乎完美地做到了这一点。不过有一个问题,我尝试了en.cppreference.com/w/cpp/thread/condition_variable/wait 的示例,但我不明白为什么第一个使用cv_m 作为参数创建std::unique_lock 的线程被阻止,因为他是第一个锁定互斥锁的线程(在unique_locks 构造函数)。 在该示例中,等待线程可能都将获取锁,然后在等待信号时释放它。这些线程以非确定性方式获取锁的顺序,因为它们是异步运行的。然后,由于多线程的性质,它们从“等待”调用中唤醒的顺序也是未定义的。不过有一件事是肯定的,那就是每个线程在运行“cerr

以上是关于互斥锁的发生顺序是不是与询问的顺序相同?的主要内容,如果未能解决你的问题,请参考以下文章

在同一个互斥锁上的锁定和解锁顺序是不是一致?

Java的锁:公平锁,非公平锁,可重入锁,自旋锁,独占锁(写锁) / 共享锁(读锁) / 互斥锁...

多线程间的互斥(下)

使用条件变量优于互斥锁的优点

Linux驱动之并发与竞争

并发使用synchronized获取互斥锁的几点说明