互斥锁的发生顺序是不是与询问的顺序相同?
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();
要查找i
,ThreadPool
会搜索将m_bAvailable
设置为true
的线程对象。它解锁相应的互斥体,以便thread
可以锁定它并执行它的任务。 thread
立即将其解锁,因此 ThreadPool
可以再次锁定它,因此一旦完成任务,thread
就会停止。
但问题是,锁会按照线程要求的顺序进行吗?换句话说,如果thread
对mutex
进行了锁定,那么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_lock
s 构造函数)。
在该示例中,等待线程可能都将获取锁,然后在等待信号时释放它。这些线程以非确定性方式获取锁的顺序,因为它们是异步运行的。然后,由于多线程的性质,它们从“等待”调用中唤醒的顺序也是未定义的。不过有一件事是肯定的,那就是每个线程在运行“cerr
以上是关于互斥锁的发生顺序是不是与询问的顺序相同?的主要内容,如果未能解决你的问题,请参考以下文章