当 condition_variable_any
与 recursive_mutex
一起使用时,recursive_mutex
是否可以在 condition_variable_any::wait
等待时从其他线程获得?我对 Boost 和 C++11 实现都感兴趣。
这是我主要关心的用例:
void bar();
boost::recursive_mutex mutex;
boost::condition_variable_any condvar;
void foo()
{
boost::lock_guard<boost::recursive_mutex> lock(mutex);
// Ownership level is now one
bar();
}
void bar()
{
boost::unique_lock<boost::recursive_mutex> lock(mutex);
// Ownership level is now two
condvar.wait(lock);
// Does this fully release the recursive mutex,
// so that other threads may acquire it while we're waiting?
// Will the recursive_mutex ownership level
// be restored to two after waiting?
}
最佳答案
通过对 Boost 文档的严格解释,我得出的结论是 condition_variable_any::wait
通常不会导致 recursive_mutex
在等待通知时被其他线程获取。
所以 condvar.wait(lock)
将调用 lock.unlock
,后者又调用 mutex.unlock
,这将所有权级别降低一(不一定降到零)。
我编写了一个测试程序来证实我的上述结论(对于 Boost 和 C++11):
#include <iostream>
#define USE_BOOST 1
#if USE_BOOST
#include <boost/chrono.hpp>
#include <boost/thread.hpp>
#include <boost/thread/condition_variable.hpp>
#include <boost/thread/locks.hpp>
#include <boost/thread/recursive_mutex.hpp>
namespace lib = boost;
#else
#include <chrono>
#include <thread>
#include <condition_variable>
#include <mutex>
namespace lib = std;
#endif
void bar();
lib::recursive_mutex mutex;
lib::condition_variable_any condvar;
int value = 0;
void foo()
{
std::cout << "foo()\n";
lib::lock_guard<lib::recursive_mutex> lock(mutex);
// Ownership level is now one
bar();
}
void bar()
{
std::cout << "bar()\n";
lib::unique_lock<lib::recursive_mutex> lock(mutex);
// Ownership level is now two
condvar.wait(lock); // Does this fully release the recursive mutex?
std::cout << "value = " << value << "\n";
}
void notifier()
{
std::cout << "notifier()\n";
lib::this_thread::sleep_for(lib::chrono::seconds(3));
std::cout << "after sleep\n";
// --- Program deadlocks here ---
lib::lock_guard<lib::recursive_mutex> lock(mutex);
value = 42;
std::cout << "before notify_one\n";
condvar.notify_one();
}
int main()
{
lib::thread t1(&foo); // This results in deadlock
// lib::thread t1(&bar); // This doesn't result in deadlock
lib::thread t2(¬ifier);
t1.join();
t2.join();
}
我希望这可以帮助其他人在混合
condition_variable_any
和 recursive_mutex
时面临同样的困境。关于c++ - 与 recursive_mutex 一起使用时 condition_variable_any 的行为?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11752155/