2012-08-11 16 views
6

buena gente día,de 64 bits y 32 bits de intercomunicación proceso de impulso :: message_queue

Actualmente estoy tratando de encontrar una manera de pasar datos entre un proceso de 64 bits y un proceso de 32 bits. Como es una aplicación en tiempo real y ambos se ejecutan en la misma computadora, utilizo la memoria compartida (shm).

Mientras buscaba algún mecanismo de sincronización usando shm, me sentí en boost :: message_queue. Sin embargo, no está funcionando.

Mi código es básicamente la siguiente:

parte del remitente

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

parte del receptor

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

Este código funciona perfectamente si los dos procesos son de 64 bits o 32 bits. Pero no funciona si los dos procesos no son lo mismo.

Mirando más profundamente en el impulso (1.50.0) código que veremos la siguiente línea en message_queue_t :: do_receive (realce/entre procesos/IPC/message_queue.hpp):

scoped_lock lock(p_hdr->m_mutex);

Por alguna razón, en el mutex parece estar bloqueado cuando se trabaja con procesos heterogéneos. Creo que el mutex está compensado y, por lo tanto, su valor está dañado, pero no estoy seguro.

¿Estoy tratando de lograr algo que simplemente no es compatible?

Cualquier ayuda o consejo será apreciado.

+1

No fue una suposición descabellada, eso es exacto. Ponen el mutex en la memoria compartida y está precedido por miembros cuyo tamaño depende de la bitness. No puedes hacer que esto funcione. –

Respuesta

5

Creo que se trata de la portabilidad de offset_ptr utilizado en message_queue para apuntar a cada mensaje, incluido el encabezado mutex. La interoperabilidad de 32/64 bits debería ser compatible desde Boost 1.48.0, como se aborda en https://svn.boost.org/trac/boost/ticket/5230.

Siguiendo la sugerencia de entradas, tiene la siguiente definición (hasta ahora) funcionó bien para mí en leiu de message_queue:

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

En Boost 1.50.0 bajo MSVC esto también parece requerir un pequeño parche en message_queue .hpp para resolver la ambigüedad de la plantilla: argumentos de conversión en llamadas a ipcdetail :: get_rounded_size (...).

+0

¡Gracias, James! Al observar la fuente, ese error de plantilla se corrigió en [1.57] (http: //www.boost.org/doc/libs/1_57_0/boost/interprocess/ipc/message_queue.hpp) pero todavía está presente en [1.56] (http://www.boost.org/doc/libs/1_56_0/boost/interprocess/ipc/message_queue .hpp). –

1

Pasé todo mi día de trabajo para descubrir la solución y finalmente lo hice funcionar. La solución es parcialmente lo que James proporcionó, así que usé la interop_message_queue en los procesos de 32 bits y de 64 bits.

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

El problema es que con esta modificación el código no se compilará, por lo que también tuvo que añadir lo siguiente, que he encontrado en la lista de informes de errores impulso (#6147: message_queue sample fails to compile in 32-bit), este código tiene que ser antes el impulso incluye la 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; 
     } 
    } 
    } 
} 
Cuestiones relacionadas