当 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
在等待通知时被其他线程获取。
Class
condition_variable_any
template<typename lock_type> void wait(lock_type& lock)
Effects:
Atomically call
lock.unlock()
and blocks the current thread. The thread will unblock when notified by a call tothis->notify_one()
orthis->notify_all()
, or spuriously. When the thread is unblocked (for whatever reason), the lock is reacquired by invokinglock.lock()
before the call to wait returns. The lock is also reacquired by invokinglock.lock()
if the function exits with an exception.
所以 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++ - condition_variable_any 与 recursive_mutex 一起使用时的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11752155/