Suspendre les pthreads sans l'aide d'état
Je veux suspendre pthreads mais apparemment, il n'y a pas une telle fonction comme pthread_suspend. J'ai lu quelque part au sujet de la suspension de pthreads utiliser les mutex et les conditions et l'a utilisé comme suit:
#include <pthread.h>
class PThread {
public:
pthread_t myPthread;
pthread_mutex_t m_SuspendMutex;
pthread_cond_t m_ResumeCond;
void start() {
pthread_create(&myPthread, NULL, threadRun, (void*)this );
}
Thread() { }
void suspendMe() {
pthread_cond_wait(&m_ResumeCond,&m_SuspendMutex);
}
void resume() {
pthread_cond_signal(&m_ResumeCond);
}
};
mais je ne comprends pas pourquoi nous avons besoin d'un mutex et l'état de suspendre et de reprendre un pthread. Est-il possible de suspendre et de reprendre sans conditions d'utilisation?
OriginalL'auteur sleep | 2010-06-29
Vous devez vous connecter pour publier un commentaire.
Votre code n'est pas correct - le
pthread_cond_wait()
exige que le mutex soit verrouillé déjà, quand vous l'appelez:Toutefois, il est toujours mauvais. Un thread peut réveiller d'
pthread_cond_wait()
à n'importe quel nom, pas nécessairement seulement quand il est signalée. Cela signifie que vous devez le couplerpthread_cond_wait()
avec une part de l'état qui encode la condition que le thread est vraiment d'attente pour - dans le cas le plus simple, il vous suffit d'utiliser une variable d'indicateur.pthread_cond_signal()
est utilisé pour dire le fil qu'il devrait se réveiller et re-vérifier l'état partagé. En appliquant cela à votre mise en œuvre:La raison pour laquelle le mutex est de protéger l'état partagé et d'éviter des conditions de course - le
pthread_cond_wait()
fonction effectue en réalité atomique-unlock-et-attendre quand il attend, ce qui permet un "raté de réveil" à éviter. Par exemple, dans ce code, le mutex empêchesuspended
de l'évolution à faux entre lessuspended = true;
etpthread_cond_wait()
lignes.Lynx: Aye, POSIX est très claire sur ce point: "les réveils Intempestifs de la pthread_cond_timedwait() ou pthread_cond_wait() les fonctions peuvent se produire." (bien que je crois que l'implémentation de Linux ne fait pas de fausses réveils).
Donc
pthread_cond_wait
est vraiment comme un lâche dogchain. Votre pitbull pourrait aller et de commencer à mordre les voisins d'une minute.Non, c'est plus comme la cloche sur le comptoir d'un magasin. Si vous sonner, le commerçant va certainement venir au comptoir et demander ce que vous voulez, mais si vous ne sonnez pas, ils pourraient venir de toute façon.
OriginalL'auteur caf
Si un fil n'était pas en attente sur une condition ou d'une autre, comment pourriez-vous le "signal" pour reprendre. Il ne peut pas arrêter l'exécution de n'importe quoi, et puis comme par magie de recommencer, de sorte qu'il attend une condition.
D'élaborer, en pthreads, la façon de reprendre un thread est en fait d'utiliser les variables de condition. Il n'y a pas une API pour suspendre/reprendre un fil d'une autre façon. En attente sur
pthread_cond_wait
est bon marché, il bloque jusqu'à ce que la condition est signalée, en n'utilisant pas (beaucoup?) CPU. Vous utilisez l'état de signal de la fil de se réveiller, et que le mutex est nécessaire pour protéger l'accès à la variable de condition et le code dans le fil lors de la réactivation de l'.Il y a une belle paragraphe ici qui décrit la même chose.
avez-vous lu la documentation de ces fonctions? Ils ne sont pas pour la synchronisation des threads, mais pour les débogueurs.
pthreads
est une bibliothèque fournissant de l'enfilage de fonctionnalités, y compris la synchronisation. Ce n'est pas une bibliothèque pour la mise en œuvre des débogueurs, et, par conséquent, il n'a pas un équivalent de fonctions conçues pour une utilisation dans les débogueursÀ partir de la documentation: "Cette fonction est principalement conçu pour une utilisation par les débogueurs. Il n'est pas destiné à être utilisé pour la synchronisation des threads. L'appel de SuspendThread sur un thread qui possède un objet de synchronisation, comme un mutex ou de la section critique, peut conduire à un blocage si le thread appelant essaie d'obtenir un objet de synchronisation détenue par un thread suspendue. Pour éviter cette situation, un thread dans une application qui n'est pas un débogueur doit le signal de l'autre thread de suspendre lui-même. Le thread cible doit être conçu de manière à regarder pour ce signal et de réagir de façon appropriée."
En fait OUI je l'ai fait hier, et j'ai réalisé que j'avais tort. J'ai décidé de rester muet sur la question, mais vous l'a fait remarquer, ce qui est bon.
OriginalL'auteur Mark B
Une condition est toujours associée à un mutex. Généralement, un thread va dormir parce qu'il attendait un changement d'état pour indiquer qu'il a du travail à faire; vous devez le mutex pour de la garde d'accéder à cet état, et l'état de signal du changement.
Se réveiller un thread sans en parler à elle, pourquoi vous ai réveillé, c'est un peu d'une chose étrange à faire, donc il n'y a pas de façon particulière de le faire; la seule façon de le faire est d'utiliser le mécanisme normal, mais avec aucun état partagé.
Si, pour une raison quelconque vous souhaitez suspendre et reprendre le fil à partir d'un autre thread, indépendamment de donner du travail à faire, alors vous pourriez être en mesure d'utiliser
pthread_kill
envoyerSIGSTOP
etSIGCONT
signaux; je n'ai jamais essayé de faire quelque chose comme ça, donc je n'ai aucune idée de savoir si ou non il est pris en charge.OriginalL'auteur Mike Seymour
Les mutex sont utilisés pour assurer l'accès exclusif , où les variables de condition sont utilisés pour synchroniser les threads sur la base des événements.
Nous avons besoin de Mutex pour s'assurer que les variables de condition de ne pas se retrouver dans une attente infinie.
Une chose à se rappeler est de Mutex opération de verrouillage et de déverrouillage sont garantis d'être atomique, mais les variables de condition n'a pas besoin d'être. j'.e Le fil peut obtenir prévue, alors que la variable de condition d'attente est à mi-chemin.
Considérons le cas suivant avec Mutex pour la variable de condition.
Thread 1
1)D'Effectuer Une Opération
2)Attendre sur la Variable de Condition
3)Continue l'Opération
Thread 2
1) d'Effectuer une opération
2)le Signal de la Variable de Condition
3)de Poursuivre l'Exploitation
Ici, dans le Fil 1 , l'étape 2 n'est pas garanti d'être atomique. Si le Thread 1 est poussé hors de l'état en cours d'EXÉCUTION par le planificateur avant la fin de l'étape 1.
Maintenant, le Thread 2 commence à s'exécuter et les signaux de la variable de condition. Lorsque le Thread 1 reprend l'exécution, il va finir le restant faible niveau des instructions et commence l'attente.
1 Thread se termine dans une attente infinie, comme le signal de la variable de condition s'est produit avant même de l'attente.
Donc la bonne façon de l'utiliser est (je crois que le code mentionné dans la question ne marche pas, ne le devrait)
Thread 1 :-
1)Faire le travail jusqu'au point où une certaine condition doit se produire (comme "count" doit atteindre une valeur spécifiée)
2)de Verrouillage mutex associé
3)Appel pthread_cond_wait() pour effectuer un blocage attendre le signal d'Thread1.
( À noter qu'un appel à pthread_cond_wait() automatiquement et de manière atomique déverrouille le mutex associé variable de sorte qu'il peut être utilisé par Thread2)
4)au signal de réveil. Mutex est automatiquement et de manière atomique verrouillé.
5)Explicitement déverrouiller mutex
Thread2
1)Faire le travail
2)de Verrouillage mutex associé
3)Variation de la valeur de la variable globale qui Thread1 est en attente.
4)Vérifier la valeur de la global Thread1 attendre variable. Si elle remplit la condition souhaitée, signal Thread1.
5)Déverrouiller mutex.
Continuer
OriginalL'auteur pv.
Il semble que il ya pas de n'importe quel Linux solutions de rechange de l'API de Windows SuspendThread fonction. Il est impossible de mettre en pause Linux fil sans injection de code dans ce thread procédure.
SuspendThread
en mode utilisateur, le code est toujours d'odeurs. Même la documentation dit "Cette fonction est principalement conçu pour une utilisation par les débogueurs. Il n'est pas destiné à être utilisé pour la synchronisation des threads.", ce qui devrait être suffisant pour tous ceux qui souhaitent l'utiliser.OriginalL'auteur Vitaliy
Plus au point - qu'êtes-vous en fin de compte essayer de faire?? - Je soupçonne que la réponse n'est pas "suspendre à un fil". Il se peut que la conception de votre programme a un problème.
OriginalL'auteur jim mcnamara