Estoy teniendo un problema con pthreads donde creo que me estoy quedando estancado. Creé una cola de bloqueo que pensé que estaba funcionando, pero después de hacer más pruebas descubrí que si intento cancelar varios hilos que están bloqueando en la secuencia de bloqueo, parece que tengo un punto muerto.C++ pthread bloqueo de interbloqueo de cola (creo)
La cola de bloqueo es muy simple y se ve así:
template <class T> class Blocking_Queue
{
public:
Blocking_Queue()
{
pthread_mutex_init(&_lock, NULL);
pthread_cond_init(&_cond, NULL);
}
~Blocking_Queue()
{
pthread_mutex_destroy(&_lock);
pthread_cond_destroy(&_cond);
}
void put(T t)
{
pthread_mutex_lock(&_lock);
_queue.push(t);
pthread_cond_signal(&_cond);
pthread_mutex_unlock(&_lock);
}
T pull()
{
pthread_mutex_lock(&_lock);
while(_queue.empty())
{
pthread_cond_wait(&_cond, &_lock);
}
T t = _queue.front();
_queue.pop();
pthread_mutex_unlock(&_lock);
return t;
}
priavte:
std::queue<T> _queue;
pthread_cond_t _cond;
pthread_mutex_t _lock;
}
Para la prueba, he creado 4 hilos que tiran en esta cola de bloqueo. Agregué algunas declaraciones de impresión a la cola de bloqueo y cada hilo está llegando al método pthread_cond_wait(). Sin embargo, cuando intento llamar a pthread_cancel() y pthread_join() en cada subproceso, el programa simplemente cuelga.
También he probado esto con solo un hilo y funciona perfectamente.
De acuerdo con la documentación, pthread_cond_wait() es un punto de cancelación, por lo que llamar cancelar en esos hilos debería hacer que dejen de ejecutarse (y esto solo funciona con 1 hilo). Sin embargo, pthread_mutex_lock no es un punto de cancelación. ¿Podría estar sucediendo algo en la línea de cuando se llama pthread_cancel(), el hilo cancelado adquiere el mutex antes de terminar y no lo desbloquea, y luego, cuando se cancela el siguiente hilo, no puede adquirir el mutex y los bloqueos? O hay algo más que estoy haciendo mal.
Cualquier consejo sería encantador. Gracias :)
trate de usar [Helgrind] (http://valgrind.org/info/tools.html#helgrind), que ha sido útil en el pasado para mí para detectar condiciones de carrera y puntos muertos. – Flexo
La cancelación puede ser traicionera. Por favor, muéstranos más de tu lógica: ¿cuál es el estado de cancelabilidad de tus hilos de trabajo?¿Qué limpiadores manejan? ¿Y cómo estás secuenciando las llamadas para cancelar/unir múltiples hilos? – pilcrow