Quelle est la meilleure solution pour mettre en pause et reprendre pthreads?
J'ai trouvé la rubrique suivante (ici) sur les pthreads, mais il y a beaucoup de bonnes solutions.
Je voulais savoir si le morceau de code suivant est valide, et si oui, pourquoi le même verrou est utilisé pour appeler pthread_cond_wait ainsi que l'accès et ensuite débloqué tout de suite:
void suspendMe()
{
pthread_mutex_lock(&m_SuspendMutex);
pthread_cond_wait(&m_ResumeCond, &m_SuspendMutex);
pthread_mutex_unlock(&m_SuspendMutex);
}
Ne serait-il pas préférable d'utiliser 2 mutex ici, ou est-ce la bonne façon de suspendre un pthread??
Merci d'avance!
EDIT:
Impressionnant de réponses, merci à tous.
Juste une question connexe. Depuis que j'ai envie de reprendre un fil séparément dans une autre fonction, cela serait-il plus approprié à la reprise de l'?
void suspendMe()
{
pthread_mutex_lock(&m_SuspendMutex);
pthread_cond_wait(&m_ResumeCond, &m_SuspendMutex);
}
void resumeMe()
{
pthread_cond_signal(&m_ResumeCond);
pthread_mutex_unlock(&m_SuspendMutex);
}
Merci encore à tous!! :~)
source d'informationauteur Chef Pharaoh
Vous devez vous connecter pour publier un commentaire.
En fait, ce code n'est pas thread-safe. Le mutex n'est pas réellement protéger quoi que ce soit, laissant le prédicat implicite vulnérables à des conditions de course.
Regardez ce code -- qu'est-ce que le mutex protéger? Ce qui protège la suspendre/reprendre l'état?
C'est correct:
Le fil doit appeler
checkSuspend
à la sécurité des points où il peut être suspendu. D'autres threads peuvent appelersuspendMe
etresumeMe
à suspendre/reprendre le fil.Remarquer que maintenant le mutex protège la
m_SuspendFlag
variable, en veillant à ce que le fil est dit de suspendre, dit de la reprendre, et vérifie s'il convient de suspendre ou de rester en suspension sous protection, ce qui rend le code thread-safe.À l'aide de deux mutex irait à l'encontre de l'ensemble du point de variables de condition. L'ensemble du mécanisme par lequel ils travaillent est que vous pouvez vérifier s'il ya quelque chose que vous devriez attendre et puis atomiquement attendre sans organiser de la serrure pendant que vous attendez ou d'avoir à libérer le verrou et puis attendre. Si vous maintenez la serrure pendant que vous attendez, comment pouvez-toute autre thread changement de l'état? Et si vous relâchez le verrou et puis attendre, qu'advient-il si vous manquez le changement d'état?
Par la voie, il a presque jamais fait sens pour mettre en pause ou reprendre un fil. Si vous vous sentez comme vous avez besoin d'interrompre un thread à partir de l'extérieur, qui indique simplement que vous avez codé le thread pour faire quelque chose que vous n'avez pas vraiment envie de faire. Des Questions à propos de la suspension ou de la reprise de threads est souvent l'indication d'un mauvais modèle mental de fil de la programmation. Un thread peut avoir besoin d'attendre pour quelque chose, mais il ne devrait pas être "suspendu" de l'extérieur, car il faut déjà savoir par son propre codage quand il ne devrait pas, en particulier peu de travail.
Ce est la bonne façon.
pthread_cond_wait
déverrouillem_SuspendMutex
puis attend surm_ResumeCond
et puis verrouillem_SuspendMutex
avant de reprendre.La raison pour laquelle il fonctionne de cette façon est parce que les variables de condition sont utilisés pour signaler un changement d'état, et puisque cet état est partagée, elle doit être verrouillé alors que certains thread est d'y accéder. E. g. envisager de mettre en œuvre une file d'attente d'événements:
Noter que:
qu
est synchronisé à l'aide de lamutex
.mutex
afin de permettre aux autres threads pour ajouter des éléments à la file d'attente, et quand il ont changé, nous devons verrouiller lemutex
de nouveau pour inspecter la file d'attente. C'est exactement ce quepthread_cond_signal
.Oui.
La
pthread_cond_wait()
nécessite un mutex verrouillé. C'est à cause de la façon dont la condition varaibles sont utilisés. Normalement, ils sont utilisés comme ceci:De sorte que vous acquérir le verrou en disant que vous souhaitez modifier les ressources protégées par la serrure. Mais si l'objet n'est pas dans un
ready()
état, vous suspendre votre fil avecpthread_cond_wait()
qui suspend le thread et déverrouille le mutex (permettant ainsi à d'autres threads pour l'acquisition de la serrure et potentiellement transformer l'objet enready()
état).Lorsque l'état prêt est atteint, le
m_ResumeCond
est signalé et un thread en attente est libéré de la suspension. Mais avant qu'il soit autorisé à quitterpthread_cond_wait()
il doit reaquire la serrure surm_SuspendMutex
pour s'assurer qu'il est le seul fil de modifier les ressources protégées par le mutex.Assurez-vous que le dessus est fait correctement dans un atomique de la mode (le déverrouiller/suspendre/reprendre/lock) doit en fait par
pthread_cond_wait()
.Pas.
Aussi bonne que les autres, je suppose.