2012-08-11 12 views
6

Gute Tag Leute,64bit und 32bit Prozess Sprech boost :: message_queue

Ich bin derzeit versucht, einen Weg finden, um Daten zwischen einem 64-Bit-Prozess und einem 32-Bit-Prozess zu übergeben. Da es sich um eine Echtzeitanwendung handelt und beide auf demselben Computer ausgeführt werden, verwende ich Shared Memory (shm).

Während ich nach einem Synchronisationsmechanismus mit shm suchte, fühlte ich mich auf boost :: message_queue. Aber es funktioniert nicht.

Mein Code ist im Grunde die folgenden:

Sender Teil

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

Empfängerteil

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

Dieser Code funktioniert perfekt, wenn die beiden Verfahren 64bit oder 32bit sind. Aber funktioniert nicht, wenn die beiden Prozesse nicht identisch sind.

Blick tiefer in Boost (1.50.0) Code, den Sie die folgende Zeile in message_queue_t sehen werden :: do_receive (Boost/Inter/IPC/message_queue.hpp):

scoped_lock lock(p_hdr->m_mutex);

Aus irgendeinem Grund, in der Mutex scheint bei heterogenen Prozessen gesperrt zu sein. Meine wilde Vermutung wäre, dass der Mutex versetzt ist und daher sein Wert ist beschädigt, aber ich bin mir nicht ganz sicher.

Versuche ich etwas zu erreichen, das einfach nicht unterstützt wird?

Jede Hilfe oder Beratung wird geschätzt.

+1

Das war keine wilde Vermutung, das ist richtig. Sie setzen den Mutex in den gemeinsamen Speicher und ihm gehen Elemente voraus, deren Größe von der Bissigkeit abhängt. Das kann nicht funktionieren. –

Antwort

5

Ich denke, das ist über die Portabilität von Offset_ptr in Message_queue verwendet, um auf jede Nachricht, einschließlich der Header Mutex zeigen. Die 32-/64-Bit-Interoperabilität sollte seit Boost 1.48.0 unterstützt werden, wie in https://svn.boost.org/trac/boost/ticket/5230 angesprochen.

das Ticket Vorschlag Folgen, die folgende Definition hat (bisher) arbeiteten für mich in leiu von message_queue fein:

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

On-Boost 1.50.0 unter MSVC dies auch einen kleinen Patch in message_queue zu erfordern scheint .hpp, um die Mehrdeutigkeit der Vorlage zu lösen: Argumente in Aufrufen von ipcdetail :: get_rounded_size (...) übergeben.

+0

Danke, James! Mit Blick auf die Quelle wurde dieser Vorlagenfehler in [1.57] behoben (http: //www.boost.org/doc/libs/1_57_0/boost/interprocess/ipc/message_queue.hpp), ist aber immer noch in [1.56] (http://www.boost.org/doc/libs/1_56_0/boost/interprocess/ipc/message_queue) vorhanden .hpp). –

1

Ich habe meinen ganzen Arbeitstag damit verbracht, die Lösung herauszufinden, und schließlich habe ich es zum Laufen gebracht. Die Lösung ist teilweise, was James zur Verfügung gestellt hat, also habe ich die interop_message_queue sowohl für die 32-Bit- als auch für die 64-Bit-Prozesse verwendet.

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

Das Problem ist, dass der Code mit dieser Änderung würde nicht kompilieren, also musste ich auch folgende hinzuzufügen, die ich auf der Boost-Bug-Report-Liste gefunden (#6147: message_queue sample fails to compile in 32-bit), hat dieser Code vorhanden sein, bevor Der Boost beinhaltet die 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; 
     } 
    } 
    } 
}