我试图将应用程序从使用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;
}
以下代码代表我试图将上面的工作代码从使用name_mutex
和named_condition
更改为使用file_lock
和named_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
实现有什么问题?
答案 0 :(得分:0)
这似乎是由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
{的“本地”成员实例(即,仅在堆栈上,不在共享内存中) {1}},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
。这类似于this->internal_cond()
类的实现方式。