gpt4 book ai didi

c++ - condition_variable_any 与 recursive_mutex 一起使用时的行为?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:38:19 25 4
gpt4 key购买 nike

condition_variable_anyrecursive_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 to this->notify_one() or this->notify_all(), or spuriously. When the thread is unblocked (for whatever reason), the lock is reacquired by invoking lock.lock() before the call to wait returns. The lock is also reacquired by invoking lock.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(&notifier);
t1.join();
t2.join();
}

我希望这可以帮助其他人在混合时面临同样的困境 condition_variable_anyrecursive_mutex .

关于c++ - condition_variable_any 与 recursive_mutex 一起使用时的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11752155/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com