首页 > 解决方案 > Boost进程间named_condition_any不通知

问题描述

我正在尝试将应用程序从使用切换boost::interprocess::named_mutexboost::interprocess::file_lock进程间同步,但是当我这样做时,我注意到我的条件变量从未被唤醒。

我创建了两个示例来演示我所做的更改类型和我看到的问题。在这两个示例中,如果使用任何参数调用同一应用程序,则应定期发送通知,或者如果使用不带参数调用,则应等待通知

最初我的应用程序使用name_mutexnamed_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_mutexnamed_conditionusing file_lockandnamed_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实施做错了什么?

标签: c++boost

解决方案


这似乎是由boost::interprocess::named_condition_any.

boost::interprocess::named_condition_any是使用 的实例实现的boost::interprocess::ipcdetail::shm_named_condition_anyboost::interprocess::ipcdetail::shm_named_condition_any将与其实现相关的所有成员变量聚合到一个名为internal_condition_members. 当shm_named_condition_any被构造时,它要么创建要么打开共享内存。如果它创建共享内存,它还会internal_condition_members在该共享内存中实例化一个对象。

问题是shm_named_condition_any它还维护一个对象的“本地”(即只是在堆栈上,而不是在共享内存中)成员实例internal_condition_members,并且它的waittimed_waitnotify_onenotify_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类的实现方式。


推荐阅读