Pergunta

Meu cenário: um servidor e alguns clientes (embora não muitos). O servidor só pode responder a um cliente de cada vez, para que eles devem ser na fila. Eu estou usando um mutex (boost::interprocess::interprocess_mutex) para fazer isso, envolto em um boost::interprocess::scoped_lock.

A coisa é, se um cliente morre inesperadamente (ou seja, não destructor runs), mantendo o mutex, os outros clientes estão em apuros, porque eles estão à espera de que a exclusão mútua. Eu considerei usando espera temporizada, por isso, se espera I do cliente para, digamos, 20 segundos e não obter o mutex, ele vai à frente e fala com o servidor de qualquer maneira.

Os problemas com esta abordagem: 1) ele faz isso toda vez. Se está em um loop, falando constantemente para o servidor, ele precisa esperar o tempo limite de cada vez. 2) Se há três clientes e um deles morre, mantendo o mutex, os outros dois vão apenas esperar 20 segundos e falar com o servidor ao mesmo tempo - exatamente o que eu estava tentando evitar

.

Assim, como posso dizer a um cliente, "hey lá, parece que este mutex foi abandonado, tomar posse dela"?

Foi útil?

Solução

Infelizmente, este não é suportado pelo boost :: interprocess API como está. Existem algumas maneiras que você pode implementar isso no entanto:

Se você estiver em uma plataforma POSIX com suporte para pthread_mutexattr_setrobust_np, editar boost / interprocess / sync / POSIX / thread_helpers.hpp e boost / interprocess / sync / POSIX / interprocess_mutex.hpp usar mutexes robustos, e para lidar de alguma forma o EOWNERDEAD retornar de pthread_mutex_lock.

Se você estiver em alguma outra plataforma, você pode editar boost / interprocess / sync / emulação / interprocess_mutex.hpp usar um contador de geração, com a bandeira trancada no pouco menor. Em seguida, você pode criar um protocolo de recuperação que irá definir um sinalizador na palavra de bloqueio para indicar uma recuperação pendente, em seguida, fazer um-and-swap comparar após um tempo limite para verificar se a mesma geração ainda está na palavra de bloqueio, e se assim substituir -lo com um valor de próxima geração bloqueado.

Se você estiver no Windows, outra boa opção seria a utilização de objetos mutex nativas; eles provavelmente vai ser mais eficiente do que o ocupado-à espera de qualquer maneira.

Você também pode querer reconsiderar o uso de um protocolo de memória compartilhada -? Por que não usar um protocolo de rede em vez

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top