8

各位好日子

我目前正在尝试寻找一种在 64 位进程和 32 位进程之间传递数据的方法。由于它是一个实时应用程序,并且两者都在同一台计算机上运行,​​因此我很难使用共享内存 (shm)。

当我在寻找一些使用 shm 的同步机制时,我感觉到了 boost::message_queue。但是它不起作用。

我的代码基本上如下:

发件人部分

message_queue::remove("message_queue");
message_queue mq(create_only, "message_queue", 100, sizeof(uint8_t));
for (uint8_t i = 0; i < 100; ++i)
{
    mq.send(&i, sizeof(uint8_t), 0);
}

接收器部分

message_queue mq(open_only, "message_queue");
for (uint8_t i = 0; i < 100; ++i)
{
    uint8_t v;
    size_t rsize;
    unsigned int rpriority;
    mq.receive(&v, sizeof(v), rsize, rpriority);
    std::cout << "v=" << (int) v << ", esize=" << sizeof(uint8_t) << ", rsize=" << rsize << ", rpriority=" << rpriority << std::endl;
}

如果两个进程是 64 位或 32 位,则此代码可以完美运行。但是如果两个过程不相同,则不起作用。

深入了解 boost (1.50.0) 代码,您将在 message_queue_t::do_receive (boost/interprocess/ipc/message_queue.hpp) 中看到以下行:

scoped_lock lock(p_hdr->m_mutex);

由于某种原因,在使用异构进程时,互斥锁似乎被锁定。我的疯狂猜测是互斥锁被抵消了,因此它的价值被破坏了,但我不太确定。

我是否正在尝试完成一些根本不受支持的事情?

任何帮助或建议将不胜感激。

4

2 回答 2

5

我认为这与 message_queue 中使用的 offset_ptr 的可移植性有关,以指向每条消息,包括标头互斥体。自 Boost 1.48.0 起应支持 32 位/64 位互操作性,如https://svn.boost.org/trac/boost/ticket/5230中所述。

根据票证建议,以下定义(到目前为止)在 message_queue 的 leiu 中对我来说效果很好:

typedef message_queue_t< offset_ptr<void, int32_t, uint64_t> > interop_message_queue;

在 MSVC 下的 Boost 1.50.0 上,这似乎还需要在 message_queue.hpp 中添加一个小补丁来解决模板歧义:在调用 ipcdetail::get_rounded_size(...) 时转换参数。

于 2012-09-20T16:10:57.437 回答
1

我花了整个工作日找出解决方案,最后我成功了。解决方案部分是 James 提供的,所以我在 32 位和 64 位进程上都使用了 interop_message_queue。

typedef boost::interprocess::message_queue_t< offset_ptr<void, boost::int32_t, boost::uint64_t>> interop_message_queue;

问题是通过此修改代码无法编译,因此我还必须添加以下内容,这是我在 boost 错误报告列表中找到的(#6147: message_queue sample failed to compile in 32-bit),这段代码有在提升包括 message_queue 之前放置:

namespace boost {
  namespace interprocess {
    namespace ipcdetail {
      //Rounds "orig_size" by excess to round_to bytes
      template<class SizeType, class ST2>
      inline SizeType get_rounded_size(SizeType orig_size, ST2 round_to) {
        return ((orig_size-1)/round_to+1)*round_to;
      }
    }
  }
}
于 2013-03-02T06:37:24.147 回答