Linux Threads suspendre/reprendre
Je suis en train d'écrire un code dans lequel j'ai deux threads s'exécutant en parallèle.
1er est le thread principal qui a commencé le 2ème fil.
2ème thread est juste un simple thread exécutant vide boucle while.
Maintenant je veux m'arrêter, de suspendre l'exécution de la 2ème fil le 1er thread qui l'a créé.
Et après quelques temps, j'ai envie de reprendre l'exécution de la 2ème fil (par l'émission d'une commande ou d'une fonction), d'où elle a été interrompue ou suspendue.
OriginalL'auteur ZeeAzmat | 2012-07-13
Vous devez vous connecter pour publier un commentaire.
Cette question n'est pas sur la façon d'utiliser les mutex, mais comment faire pour suspendre à un fil.
Dans les spécifications Unix il y a une fonction de thread appelé pthread_suspend, et un autre appelé pthread_resume_np, mais pour une raison quelconque, les gens qui font de Linux, FreeBSD, NetBSD, et ainsi de suite n'ont pas mis en œuvre ces fonctions.
Afin de les comprendre, les fonctions ne sont tout simplement pas là. Il existe des solutions de contournement, mais malheureusement il n'est juste pas la même que l'appel à la SuspendThread sur windows. Que vous avez à faire tous les types de non-portable trucs pour faire un fil d'arrêter et de commencer à l'aide de signaux.
D'arrêt et de reprise des threads est vital pour les débogueurs et ramasseurs d'ordures. Par exemple, j'ai vu une version de Wine qui n'est pas capable de mettre en œuvre le "SuspendThread" de la fonction. Ainsi, tout programme windows en utilisant il ne fonctionnera pas correctement.
J'ai pensé qu'il était possible de le faire correctement à l'aide des signaux basé sur le fait que la JVM utilise cette technique de signaux pour le Garbage collector, mais j'ai aussi vu quelques articles en ligne où les gens remarquent les blocages et ainsi de suite avec la JVM, parfois unreproducable.
De sorte à arriver à répondre à la question, vous ne parvenez pas à suspendre et de reprendre les discussions avec Unix, sauf si vous avez une belle Unix qui implémente pthread_suspend_np. Sinon, vous êtes coincé avec les signaux.
Le gros problème avec les Signaux, c'est quand vous avez environ cinq bibliothèques différentes, toutes reliées au même programme et tous les mêmes signaux en même temps. Pour cette raison, je crois que vous ne pouvez utiliser quelque chose comme ValGrind, par exemple, le GC de Boehm dans un seul programme. Au moins sans codage au niveau le plus bas de l'espace utilisateur.
Une autre réponse à cette question pourrait être. Faire ce Linuz Torvalds n'NVidia, retournez le doigt sur lui et l'amener à mettre en œuvre les deux parties essentielles manquantes à partir de Linux. Tout d'abord, pthread_suspend, et la seconde, une sale peu sur les pages de mémoire, de sorte que la bonne éboueurs peuvent être mises en œuvre. Lancer une grande pétition en ligne et rester appuyer sur le doigt. Peut-être par les Fenêtres de temps de 20 sort, ils se rendront compte que la Suspension et la reprise de threads, et ayant sale bits est en fait l'une des raisons fondamentales de Windows et Mac sont mieux que Linux, ou tout Unix qui ne mettent pas en œuvre pthread_suspend et aussi un sale peu sur les pages virtuelles, comme VirtualAlloc dans Windows.
Je ne pas vivre dans l'espérance. En fait pour moi, j'ai passé un certain nombre d'années, la planification de mon avenir autour de la construction des trucs pour Linux, mais ont abandonné l'espoir fiable chose tout semble dépendre de la disponibilité d'un bit d'impureté pour la mémoire virtuelle, et pour suspendre les fils proprement.
La partie 2) la Plupart des systèmes, que "mettre en œuvre" la suspension de threads, ne sont pas à l'abri de blocages, ils suffit de pousser la responsabilité des utilisateurs. "SuspendThread" n'est pas parfaitement sûr de soit, c'est juste suppose que vous savez ce que vous faites. Linux n'est pas à blâmer pour le manque de soutien, en fait, la plupart des appels système sont interruptible/réentrant, c'est pourquoi les signaux travail. L'espace utilisateur des bibliothèques (notamment de la libc malloc et thread local storage) sont les plus grands délinquants quand il s'agit de la réentrée et d'annulation.
VxWorks (pas un Unix) met en œuvre taskSuspend et taskResume. Un de leur mise en œuvre pourrait fournir quelques idées.
OriginalL'auteur
Autant que je sache, vous ne pouvez pas simplement mettre en pause un autre thread à l'aide de pthreads. Vous devez avoir quelque chose dans votre 2ème thread qui vérifie de temps il devrait être mis en pause à l'aide de quelque chose comme une variable de condition. C'est le moyen standard pour faire ce genre de chose.
+1 ... et ajoutant à cela: Même si vous , alors vous ne devrait pas suspendre des threads. Toujours attendre sur une variable de condition ou d'un semblable primitives de synchronisation, jamais faire quelque chose de différent. Suspension (ou pire, tuer) les threads cause d'un grand mal. Il est moyennement difficile/facile d'obtenir un blocage ou des résultats inattendus à l'aide de primitives de synchronisation. Cependant, il est un normal ce qui se passe tout le temps en cas de suspension (ou tuer) threads. Et il est presque impossible de debug...
Dort avec l'aide d'un sémaphore de la variable n'est pas une pause?
Pas sûr de ce que tu veux dire, mais je veux dire que vous ne pouvez pas explicitement pause l'autre fil dans les pthreads explicitement. Bien sûr threads en pause à tout moment pour diverses raisons.
Eh bien, vous sorte de de le faire, à l'aide de
pthread_kill(...SIGSTOP)
, mais il n'y a aucune prise en charge explicite, ce serait juste de le faire. Mais je conseille fortement contre elle. La suspension d'un thread s'arrête n'importe où il est, peu importe ce qu'il fait (il pourrait par exemple y placer un verrou, ou demi-finis de données). Bloque sur un condvar/sémaphore s'arrête l'exécution à un point connu dans le temps avec le bien-connu de l'état, d'une manière contrôlée. Pas de surprises, pas d'effets secondaires inconnus.OriginalL'auteur Francis Upton
Il n'y a pas de pthread_suspend(), pthread_resume() type d'Api POSIX.
Pour la plupart des variables de condition peut être utilisé pour contrôler l'exécution des autres threads.
Pour plus d'info
Pthreads
Linux Tutoriel Threads Posix
OriginalL'auteur Jeyaram
Si vous pouvez utiliser les processus au lieu de cela, vous pouvez envoyer de l'emploi des signaux de contrôle (SIGSTOP /son état) pour le second processus. Si vous souhaitez partager la mémoire entre les processus, vous pouvez utiliser SysV de mémoire partagée (shmop, shmget, shmctl...).
Même si je n'ai pas essayé moi-même, il pourrait être possible d'utiliser le niveau inférieur clone() syscall pour frayer fils, qui ne partagent pas les signaux. Avec ceci, vous pourriez être en mesure d'envoyer SIGSTOP et son état à l'autre thread.
OriginalL'auteur Jah
Vous pouvez utiliser les mutex pour ce faire, le pseudo-code serait:
J'ai eu la même idée, le même trouvé pthread_kill fonction tah à mon esprit doit de travailler en tant que fonction kill pour les processus de stackoverflow.com/questions/11046720/...
OriginalL'auteur aisbaa
Vous ne savez pas si vous allez aimer ma réponse ou pas. Mais vous pouvez y arriver de cette façon.
Si c'est un processus distinct au lieu d'un fil, j'ai une solution(Cela peut même travailler pour le fil, peut-être quelqu'un pouvez partager vos pensées) à l'aide des signaux.
Il n'y a pas de système actuellement en place pour mettre en pause ou de reprendre l'exécution du processus. Mais sûrement, vous pouvez en construire un.
Étapes que je ferais si je le veux dans mon projet:
Enregistrer un gestionnaire de signal pour le second processus.
À l'intérieur du gestionnaire de signal, attendez un sémaphore.
Chaque fois que vous voulez mettre en pause l'autre processus, il suffit d'envoyer un signal
que vous avez enregistré les autres processus. Le programme va aller dans
l'état de sommeil.
Lorsque vous voulez reprendre le processus, vous pouvez envoyer un autre signal
de nouveau. L'intérieur que gestionnaire de signal, vous allez vérifier si le sémaphore est
verrouillé ou non. S'il est verrouillé, vous permettra de libérer le sémaphore. Donc
le processus 2 continuera son exécution.
Si vous pouvez le mettre en œuvre, s'il vous plaît partagez votre feedack si cela fonctionne pour vous ou pas. Merci.
Même problème qu'avec l'envoi de SIGSTOP (comme je l'ai indiqué ci-dessus, fonctionne sans écrire un gestionnaire d'ailleurs). Vous ne contrôlez pas quand il se passe ou ce que l'état le thread est dans. Si c'est le maintien d'un verrou à ce moment, vous êtes en difficulté.
OriginalL'auteur mk..
Pour la mise en œuvre de la pause sur un fil, vous avez besoin de le faire attendre un événement se produise. En attente sur un spin-lock mutex est CPU cycle de gaspiller. À mon humble avis, cette méthode ne doit pas être suivi comme les cycles de PROCESSEUR pourrait avoir été utilisé par d'autres processus/threads.
Attendre sur un non-descripteur de blocage (pipe, socket ou une autre). Exemple de code pour l'utilisation de des tuyaux pour la communication inter-thread peut être vu ici
Solution ci-dessus est utile, si votre deuxième thread a plus d'informations à partir de plusieurs sources que de simplement le mettre en pause et reprendre des signaux. Un haut niveau select/poll/epoll peut être utilisé sur la non-blocage des descripteurs. Vous pouvez spécifier le temps d'attente pour les select/poll/epoll les appels système, et seulement ce micro-secondes de cycles CPU sera gaspillé.
Je vous parle de cette solution avant-gardiste que votre deuxième thread aura plus de choses ou d'événements à gérer que de la pause et de reprise. Désolé si c'est plus détaillé que ce que vous avez demandé.
Une autre approche la plus simple peut être d'avoir partagé variable booléenne entre ces threads.
Thread principal est l'écrivain de la variable, de 0 signifie arrêter. 1 - signifie reprendre
Deuxième thread ne lit la valeur de la variable. Pour mettre en œuvre '0' état, l'utilisation usleep pour sime micro-secondes, puis vérifiez de nouveau la valeur. En supposant que, quelques micro-secondes de retard est acceptable dans votre conception.
Pour mettre en œuvre '1' - vérifier la valeur de la variable après avoir fait un certain nombre d'opérations.
Sinon, vous pouvez également mettre en place un signal pour passer de '1' à '0' état.
OriginalL'auteur Groovy
Vous pouvez suspendre un fil tout simplement par le signal
OriginalL'auteur user8549285