加速进程间named_condition_any通知

时间:2018-09-12 01:45:54

标签: c++ boost

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

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

最初,我的应用程序使用了name_mutexnamed_condition。下面使用name_mutexnamed_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_mutexnamed_condition更改为使用file_locknamed_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实现有什么问题?

1 个答案:

答案 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_waitnotify_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()类的实现方式。