c++ - Boost进程间named_condition_any不通知
问题描述
我正在尝试将应用程序从使用切换boost::interprocess::named_mutex
到boost::interprocess::file_lock
进程间同步,但是当我这样做时,我注意到我的条件变量从未被唤醒。
我创建了两个示例来演示我所做的更改类型和我看到的问题。在这两个示例中,如果使用任何参数调用同一应用程序,则应定期发送通知,或者如果使用不带参数调用,则应等待通知
最初我的应用程序使用name_mutex
和named_condition
. 下面的示例使用name_mutex
并按named_condition
预期工作:每次“发送方”应用程序打印出“通知”时,“接收方”应用程序都会打印出“通知!” (假设我在运行之间手动清理/dev/shm/
)。
#include <iostream>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/named_condition.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <boost/thread.hpp>
int main(int argc, char** argv)
{
boost::interprocess::named_mutex mutex(boost::interprocess::open_or_create,
"mutex");
// Create condition variable
boost::interprocess::named_condition cond(boost::interprocess::open_or_create, "cond");
while(true)
{
if(argc > 1)
{// Sender
std::cout << "Notifying" << std::endl;
cond.notify_all();
boost::this_thread::sleep_for(boost::chrono::seconds(1));
}
else
{// Receiver
std::cout << "Acquiring lock..." << std::endl;
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> lock(mutex);
std::cout << "Locked. Waiting for notification..." << std::endl;
cond.wait(lock);
std::cout << "Notified!" << std::endl;
}
}
return 0;
}
以下代码代表我尝试将上面的工作代码从 usingname_mutex
和named_condition
using file_lock
andnamed_condition_any
#include <iostream>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/named_condition_any.hpp>
#include <boost/interprocess/sync/file_lock.hpp>
#include <boost/thread.hpp>
int main(int argc, char** argv)
{
// Second option for locking
boost::interprocess::file_lock flock("/tmp/flock");
// Create condition variable
boost::interprocess::named_condition_any cond(boost::interprocess::open_or_create,
"cond_any");
while(true)
{
if(argc > 1)
{// Sender
std::cout << "Notifying" << std::endl;
cond.notify_all();
boost::this_thread::sleep_for(boost::chrono::seconds(1));
}
else
{// Receiver
std::cout << "Acquiring lock..." << std::endl;
boost::interprocess::scoped_lock<boost::interprocess::file_lock> lock(flock);
std::cout << "Locked. Waiting for notification..." << std::endl;
cond.wait(lock);
std::cout << "Notified!" << std::endl;
}
}
return 0;
}
但是,我似乎无法让“接收者”应用程序在收到通知时唤醒。“发送者”以 ~1Hz 的速度愉快地打印“通知”,但“接收者”在打印“已锁定。等待通知...”一次后挂起。
我的file_lock
/named_condition_any
实施做错了什么?
解决方案
这似乎是由boost::interprocess::named_condition_any
.
boost::interprocess::named_condition_any
是使用 的实例实现的boost::interprocess::ipcdetail::shm_named_condition_any
。boost::interprocess::ipcdetail::shm_named_condition_any
将与其实现相关的所有成员变量聚合到一个名为internal_condition_members
. 当shm_named_condition_any
被构造时,它要么创建要么打开共享内存。如果它创建共享内存,它还会internal_condition_members
在该共享内存中实例化一个对象。
问题是shm_named_condition_any
它还维护一个对象的“本地”(即只是在堆栈上,而不是在共享内存中)成员实例internal_condition_members
,并且它的wait
、timed_wait
、notify_one
和notify_all
函数都是使用本地internal_condition_members
成员而不是internal_condition_members
来自共享内存的来实现的。
boost/interprocess/sync/shm/named_condition_any.hpp
通过编辑和更改类的实现,我能够从我的示例中获得预期的行为,shm_named_condition_any
如下所示:
typedef ipcdetail::condition_any_wrapper<internal_condition_members> internal_condition;
internal_condition m_cond;
到
typedef ipcdetail::condition_any_wrapper<internal_condition_members> internal_condition;
internal_condition &internal_cond()
{ return *static_cast<internal_condition*>(m_shmem.get_user_address()); }
m_cond
并更改to的所有用法this->internal_cond()
。这类似于shm_named_condition
类的实现方式。
推荐阅读
- python - python元音小写和辅音大写
- java - 如何在 Android 的 Strings.xml 中搜索字符串?
- cs50 - cs50 拼写器不处理大多数单词并且大小写不敏感
- python - 在数据框中使用多个分隔符解析数据
- html - 有没有办法遍历字符串以返回 Ruby 中数组的名字、姓氏和中间名?
- android - Android RecyclerView 不绘制自定义视图;不调用 onDraw
- php - php/sql 中准备好的查询出现致命错误
- javascript - React Native:正在删除从异步函数中的 firestore 检索的数据
- c# - C# XML 查找 LIST 中属性的值 - 已解决
- configuration - 如何在 NodeRED 中包含单独的配置文件