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;
}

このコードは、2 つのプロセスが 64 ビットまたは 32 ビットの場合に完全に機能します。ただし、2 つのプロセスが同じでない場合は機能しません。

ブースト (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 の移植性に関するものだと思います。https://svn.boost.org/trac/boost/ticket/5230で対処されているように、32 ビット/64 ビットの相互運用性は Boost 1.48.0 以降でサポートされる必要があります。

チケットの提案に続いて、次の定義は(これまでのところ)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 fails 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 に答える