Emi*_*ier 4 c++ multithreading boost c++11 recursive-mutex
当使用condition_variable_anya时recursive_mutex,通常recursive_mutex可以在等待时从其他线程获取吗?我对Boost和C++ 11实现感兴趣.condition_variable_any::wait
这是我主要关注的用例:
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?
}
Run Code Online (Sandbox Code Playgroud)
通过Boost文档的严格解释,我的结论是,condition_variable_any::wait将一般不导致recursive_mutex是能够获取其他线程在等待通知.
类
condition_variable_any
template<typename lock_type> void wait(lock_type& lock)功效:
原子调用
lock.unlock()并阻塞当前线程.当通过this->notify_one()或this->notify_all()或虚假地通知时,线程将解除阻塞.当线程被解除阻塞(无论出于何种原因)时,通过lock.lock()在等待调用返回之前调用来重新获取锁.lock.lock()如果函数以异常退出,则还可以通过调用来重新获取锁.
所以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();
}
Run Code Online (Sandbox Code Playgroud)
我希望这可以帮助别人搅拌时面临着同样的困境condition_variable_any和recursive_mutex.
| 归档时间: |
|
| 查看次数: |
2242 次 |
| 最近记录: |