64位和32位进程间通信 boost::message_queue

10

大家好,

我正在尝试找到一种方法来在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);

由于某种原因,在处理异构进程时,互斥锁似乎被锁定了。 我的猜测是,由于互斥锁被偏移,因此其值已损坏,但我不能确定。

我试图实现的东西是否被支持?

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


1
那不是瞎猜,而是准确的。他们将互斥锁放在共享内存中,并且它之前有一些成员,其大小取决于位数。你无法让这个工作。 - Hans Passant
2个回答

7

我认为这与在消息队列中使用的offset_ptr的可移植性有关,其中包括头部互斥锁。从Boost 1.48.0开始,应支持32位/64位的互操作性,如https://svn.boost.org/trac/boost/ticket/5230所述。

根据票证建议,以下定义(到目前为止)对我来说已经可以替代message_queue起作用:

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(...)时强制转换参数。

谢谢你,詹姆斯!查看源代码后,发现这个模板错误已经在1.57中得到修复,但在1.56中仍然存在。 - Andreas Haferburg

4

解决方案部分参考了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 fails to compile in 32-bit)中找到的,这段代码必须放置在message_queue的boost包含之前:
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;
      }
    }
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接