c++ - sinonimos - ¿Cómo me apropio de un boost abandonado:: interprocess:: interprocess_mutex?
apropiarse sinonimo rae (1)
Mi escenario: un servidor y algunos clientes (aunque no muchos). El servidor solo puede responder a un cliente a la vez, por lo que debe estar en cola. Estoy usando un mutex ( boost::interprocess::interprocess_mutex
) para hacer esto, envuelto en un boost::interprocess::scoped_lock
.
La cuestión es que si un cliente muere inesperadamente (es decir, no se ejecuta ningún destructor) mientras mantiene el mutex, los otros clientes tienen problemas porque están esperando ese mutex. He considerado utilizar la espera temporizada, así que si el cliente espera, digamos, 20 segundos y no obtiene el mutex, sigue adelante y habla con el servidor de todos modos.
Problemas con este enfoque: 1) hace esto cada vez. Si está en un bucle, hablando constantemente con el servidor, necesita esperar el tiempo de espera cada vez. 2) Si hay tres clientes, y uno de ellos muere mientras mantiene el mutex, los otros dos esperarán 20 segundos y hablarán con el servidor al mismo tiempo, exactamente lo que estaba tratando de evitar.
Entonces, ¿cómo puedo decirle a un cliente, "oye allí, parece que este mutex ha sido abandonado, se apropia de él"?
Lamentablemente, esto no es compatible con la API boost :: interprocess tal como está. Sin embargo, hay algunas maneras de implementarlo:
Si está en una plataforma POSIX con soporte para pthread_mutexattr_setrobust_np, edite boost / interprocess / sync / posix / thread_helpers.hpp y boost / interprocess / sync / posix / interprocess_mutex.hpp para usar mutexes robustos, y para manejar de alguna manera el retorno EOWNERDEAD de pthread_mutex_lock .
Si está en otra plataforma, puede editar boost / interprocess / sync / emulation / interprocess_mutex.hpp para usar un contador de generación, con la bandera bloqueada en el bit inferior. Luego puede crear un protocolo de reclamación que establecerá un indicador en la palabra de bloqueo para indicar un reclamo pendiente, luego haga un compare-and-swap después de un tiempo de espera para verificar que la misma generación aún esté en la palabra de bloqueo, y si es así reemplace con un valor bloqueado de próxima generación.
Si está en Windows, otra buena opción sería usar objetos mutex nativos; es probable que sean más eficientes que ocupados, esperando de todos modos.
También es posible que desee reconsiderar el uso de un protocolo de memoria compartida: ¿por qué no utilizar un protocolo de red?