Je dois tirer d'un tas de fils et je voudrais les abattre gracieusement.terminaison de fil gracieuse avec pthread_cond_signal prouvant problématique
J'essaie d'utiliser pthread_cond_signal
/pthread_cond_wait
pour y parvenir mais je rencontre un problème.
Voici mon code. premièrement le thread_main
static void *thrmain(void * arg)
{
// acquire references to the cond var, mutex, finished flag and
// message queue
.....
while(true)
{
pthread_mutex_lock(&lock);
if (msq.empty())
{
// no messages so wait for one.
pthread_cond_wait(&cnd, &lock);
}
// are we finished.
if (finished)
{
// finished so unlock the mutex and get out of here
pthread_mutex_unlock(&lock);
break;
}
if (!msg.empty())
{
// retrieve msg
....
// finished with lock
pthread_mutex_unlock(&lock);
// perform action based on msg
// outside of lock to avoid deadlock
}
else
{
// nothing to do so we're
// finished with the lock.
pthread_mutex_unlock(&lock);
}
}
return 0;
}
Maintenant, tout cela semble bien et dandy (pour moi quand même).
Donc, pour arracher les fils que j'ai cette méthode
void teardown()
{
// set the global finished var
pthread_mutex_lock(&lock);
finished = true;
pthread_mutex_unlock(&lock);
// loop over the threads, signalling them
for (int i = 0 ; i < threads.size() ; ++i)
{
// send a signal per thread to wake it up
// and get it to check it's finished flag
pthread_cond_signal(&cnd);
}
// need to loop over the threads and join them.
for (int i = 0 ; i < threads.size() ; ++i)
{
pthread_join(threads[ i ].tid, NULL);
}
}
Maintenant, je sais que pthread_cond_signal
ne garantit pas quel fil il se réveille signaler que je ne peux pas et rejoindre dans la même boucle. Cependant, c'est là que tout va mal. pthread_cond_signal
ne fait rien s'il n'y a pas de thread en attente donc potentiellement certains des threads n'auront pas été signalés et ne sauront donc pas quitter.
Comment puis-je survivre à cela.
M.
***** MISE À JOUR ******* S'il vous plaît ne pas poster que je devrais utiliser pthread_cond_broadcast car cela présente le même comportement. il ne fera que réveiller un fil qui attend réellement sur la var. Tout thread qui est le traitement pendant cette période et revient à attendre plus tard aura manqué le signal et sera inconscient
Non. Il s'agit simplement d'une répétition plus élégante de la même réponse précédente: pthread_cond_broadast ne signale que les threads en attente sur la var de cond .. Si l'un des threads est en cours de traitement alors ils ne se réveilleront pas quand ils arriveront finalement à l'appel d'attente .. – ScaryAardvark
S'ils sont en cours de traitement, ils sont déjà réveillés et ils sortiront sur la prochaine boucle parce que votre démontage() tient le mutex lorsque vous avez terminé, vous êtes en sécurité – nos
+1 pour l'approche du message empoisonné. Cette approche s'est avérée être la meilleure solution dans de nombreux cas. – Tronic