在已锁定的互斥量上使用 boost::interprocess 条件变量
Using boost::interprocess condition variable on an already locked mutex
我想在已锁定的互斥量上使用 boost::interprocess 条件变量。我已经使用 mutex->lock();
函数锁定了互斥体,因此 scoped_lock 并不适合我。 boost::interprocess 中是否有任何可用的 API 可以在不使用 scoped_lock
的情况下等待条件变量?我正在寻找类似于以下内容的 API:
condition_variable.wait(mutex)
在上面的代码块中,互斥锁已经被锁定,所以不需要 scoped_lock
。但是,上面的代码块不起作用,因为 boost 期望将 lock
而不是 mutex
作为 `wait 的第一个参数。我可以使用下面的函数调用在 pthread 中做同样的事情:
pthread_cond_wait(condition_variable, mutex)
您需要一个 BasicLockable。确实 scoped_lock(或 lock_guard)不是那样。 unique_lock
类似的是:
The class unique_lock
meets the BasicLockable
requirements. If Mutex
meets the Lockable requirements, unique_lock
also meets the Lockable
requirements (ex.: can be used in std::lock
); if Mutex
meets the
TimedLockable
requirements, unique_lock
also meets the TimedLockable
requirements.
这是一个小演示,假设您的进程间互斥锁和条件的某些类型:
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/interprocess/managed_mapped_file.hpp>
#include <boost/interprocess/sync/interprocess_condition.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <mutex>
#include <thread>
namespace bip = boost::interprocess;
using namespace std::literals;
using boost::posix_time::milliseconds;
auto now = boost::posix_time::microsec_clock::universal_time;
int main() {
bip::managed_mapped_file mmf(bip::open_or_create, "mapped.dat", 32<<10);
auto& mutex = *mmf.find_or_construct<bip::interprocess_mutex>("mutex")();
auto& cond = *mmf.find_or_construct<bip::interprocess_condition>("cond")();
auto& data = *mmf.find_or_construct<int>("data")(0);
auto is_ready = [&data] { return data != 42; };
std::unique_lock lk(mutex);
/*void*/ cond.wait(lk);
/*void*/ cond.wait(lk, is_ready);
// check return values for these:
cond.timed_wait(lk, now() + milliseconds(120));
cond.timed_wait(lk, now() + milliseconds(120), is_ready);
}
(当然那会永远阻塞,因为没有任何东西通知条件)。
Added a running demo with a very quick-and-dirty signaller thread: http://coliru.stacked-crooked.com/a/a1eb29653f1bbcee
没有标准库
您可以使用等效的 Boost 类型:https://www.boost.org/doc/libs/1_76_0/doc/html/thread/synchronization.html#thread.synchronization.locks
我想在已锁定的互斥量上使用 boost::interprocess 条件变量。我已经使用 mutex->lock();
函数锁定了互斥体,因此 scoped_lock 并不适合我。 boost::interprocess 中是否有任何可用的 API 可以在不使用 scoped_lock
的情况下等待条件变量?我正在寻找类似于以下内容的 API:
condition_variable.wait(mutex)
在上面的代码块中,互斥锁已经被锁定,所以不需要 scoped_lock
。但是,上面的代码块不起作用,因为 boost 期望将 lock
而不是 mutex
作为 `wait 的第一个参数。我可以使用下面的函数调用在 pthread 中做同样的事情:
pthread_cond_wait(condition_variable, mutex)
您需要一个 BasicLockable。确实 scoped_lock(或 lock_guard)不是那样。 unique_lock
类似的是:
The class
unique_lock
meets theBasicLockable
requirements. IfMutex
meets the Lockable requirements,unique_lock
also meets theLockable
requirements (ex.: can be used instd::lock
); ifMutex
meets theTimedLockable
requirements,unique_lock
also meets theTimedLockable
requirements.
这是一个小演示,假设您的进程间互斥锁和条件的某些类型:
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/interprocess/managed_mapped_file.hpp>
#include <boost/interprocess/sync/interprocess_condition.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <mutex>
#include <thread>
namespace bip = boost::interprocess;
using namespace std::literals;
using boost::posix_time::milliseconds;
auto now = boost::posix_time::microsec_clock::universal_time;
int main() {
bip::managed_mapped_file mmf(bip::open_or_create, "mapped.dat", 32<<10);
auto& mutex = *mmf.find_or_construct<bip::interprocess_mutex>("mutex")();
auto& cond = *mmf.find_or_construct<bip::interprocess_condition>("cond")();
auto& data = *mmf.find_or_construct<int>("data")(0);
auto is_ready = [&data] { return data != 42; };
std::unique_lock lk(mutex);
/*void*/ cond.wait(lk);
/*void*/ cond.wait(lk, is_ready);
// check return values for these:
cond.timed_wait(lk, now() + milliseconds(120));
cond.timed_wait(lk, now() + milliseconds(120), is_ready);
}
(当然那会永远阻塞,因为没有任何东西通知条件)。
Added a running demo with a very quick-and-dirty signaller thread: http://coliru.stacked-crooked.com/a/a1eb29653f1bbcee
没有标准库
您可以使用等效的 Boost 类型:https://www.boost.org/doc/libs/1_76_0/doc/html/thread/synchronization.html#thread.synchronization.locks