在已锁定的互斥体上使用 boost::interprocess 条件变量

Posted

技术标签:

【中文标题】在已锁定的互斥体上使用 boost::interprocess 条件变量【英文标题】:Using boost::interprocess condition variable on an already locked mutex 【发布时间】:2021-06-07 00:26:29 【问题描述】:

我想。我已经使用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)

【问题讨论】:

什么是[条件变量和互斥体的类型(theboostcpplibraries.com/…)? 条件变量是interprocess_condition,互斥体是interprocess_mutex 【参考方案1】:

您需要一个 BasicLockable。实际上 scoped_lock (或 lock_guard )不是那样的。 unique_lock 和类似的是:

unique_lock 类满足 BasicLockable 要求。如果Mutex 满足可锁定要求,unique_lock 也满足Lockable 要求(例如:可用于std::lock);如果Mutex 满足 TimedLockable要求,unique_lock也符合TimedLockable 要求。

这是一个小演示,假设您的进程间互斥锁和条件有一些类型:

Coliru

#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);

(当然这只会永远阻塞,因为没有任何东西会通知条件)。

添加了一个 running 演示,带有一个非常快速和肮脏的信号器线程: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

【讨论】:

添加了一个 running 演示,带有一个非常快速和肮脏的信号器线程:coliru.stacked-crooked.com/a/a1eb29653f1bbcee 感谢您的详细回复!我不知道标准库锁可以与 boost 进程间锁一起使用。

以上是关于在已锁定的互斥体上使用 boost::interprocess 条件变量的主要内容,如果未能解决你的问题,请参考以下文章

Qt入门教程QObject篇线程同步

互斥体上的 CloseHandle,在 ReleaseMutex 之前 - 会发生啥?

锁定未锁定的互斥体的效率如何?互斥锁的成本是多少?

使用互斥锁锁定向量 - Boost

为啥互斥锁没有被锁定

互斥锁