2012-08-11 12 views
6

brava gente al giorno,64bit e intercomunicazione processo a 32 bit boost :: message_queue

Attualmente sto cercando di capire un modo per passare dati tra un processo a 64 bit e di un processo a 32 bit. Poiché si tratta di un'applicazione in tempo reale ed entrambi sono in esecuzione sullo stesso computer, utilizzo la memoria condivisa (shm).

Mentre cercavo un meccanismo di sincronizzazione con shm, ho sentito su boost :: message_queue. Tuttavia non funziona.

Il mio codice è sostanzialmente il seguente:

mittente parte

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

Ricevitore parte

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

Questo codice funziona perfettamente se i due processi sono a 64 bit o 32 bit. Ma non funziona se i due processi non sono gli stessi.

Guardando più in profondità nella spinta (1.50.0) Codice vedrete la seguente riga nel message_queue_t :: do_receive (boost/interprocesso/IPC/message_queue.hpp):

scoped_lock lock(p_hdr->m_mutex);

Per qualche ragione, nel il mutex sembra essere bloccato quando si lavora con processi eterogenei. La mia ipotesi sarebbe che il mutex è compensato e quindi il suo valore è corrotto, ma non ne sono del tutto sicuro.

Sto cercando di realizzare qualcosa che semplicemente non è supportato?

Qualsiasi aiuto o consiglio sarà apprezzato.

+1

Questa non era un'ipotesi selvaggia, che è accurata. Mettono il mutex nella memoria condivisa ed è preceduto da membri le cui dimensioni dipendono dal testimone. Non puoi far funzionare questo. –

risposta

5

Penso che si tratti della portabilità di offset_ptr utilizzata in message_queue per puntare a ciascun messaggio, incluso l'intestazione mutex. L'interoperabilità a 32/64 bit deve essere supportata da Boost 1.48.0, come indicato in https://svn.boost.org/trac/boost/ticket/5230.

Seguendo il suggerimento di biglietti, la seguente definizione ha (finora) ha funzionato bene per me in leiu di message_queue:

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

On Boost 1.50.0 sotto MSVC questo sembra anche a richiedere una piccola patch in message_queue .hpp per risolvere l'ambiguità dei template: casting degli argomenti nelle chiamate a ipcdetail :: get_rounded_size (...).

+0

Grazie, James! Osservando la fonte, quell'errore di modello è stato corretto in [1.57] (http: //www.boost.org/doc/libs/1_57_0/boost/interprocess/ipc/message_queue.hpp) ma è ancora presente in [1.56] (http://www.boost.org/doc/libs/1_56_0/boost/interprocess/ipc/message_queue .hpp). –

1

Ho passato tutta la giornata lavorativa a capire la soluzione e finalmente l'ho fatta funzionare. La soluzione è parzialmente fornita da James, quindi ho utilizzato l'interop_message_queue su entrambi i processi a 32 e 64 bit.

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

Il problema è che con questa modifica il codice non sarebbe compilare, così ho anche dovuto aggiungere la seguente, che ho trovato sulla lista rapporto spinta bug (#6147: message_queue sample fails to compile in 32-bit), questo codice deve essere posto prima la spinta include del 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; 
     } 
    } 
    } 
} 
Problemi correlati