C++0x fil interruption
Selon le C++0x projet final, il n'y a pas moyen de demander un fil à la fin. Cela dit, si nécessaire, nous devons mettre en œuvre un do-it-yourself solution.
D'autre part boost::thread fournit un mécanisme pour interrompre un thread dans un sûr manière.
À votre avis, quelle est la meilleure solution? La conception de votre propre coopérative "interruption mécanisme" ou natifs?
- Intéressant de noter que si vous pouvez tuer un thread, qui pourraient laisser ressources allouées dans la mémoire(depuis le thread a été tué avant que ceux-ci ont été supprimés). Je pense donc que c'est, au moins pour la plupart des cas, une bonne décision.
- Il y a même des choses pires que des fuites - tels que les transactions incomplètes, une corruption de segment de mémoire ou verrouille toujours détenus.
- si vous vous souciez de l'exactitude, vous n'avez pas vraiment le choix: ensuite, les threads ne peuvent être interrompus en collaboration, quand ils sont dans prédéfinis "interuptable" états.
- Tuer un thread est en train de mettre un nœud coulant autour de tous les autres threads' cou. Il suffit de ne pas le faire, sauf si vous êtes un sang-froid le fil killer...
- double possible de Comment puis-je arrêter un thread en C++11? le Choix de l'autre parce qu'il est un peu plus général.
Vous devez vous connecter pour publier un commentaire.
Tous le langage de spécification indique que le soutien n'est pas intégré dans la langue.
boost::thread::interrupt
besoin d'un certain soutien de la fonction de thread, trop:Lors de l'interruption du fil suivant exécute une ou de l'interruption des points (ou si elle est actuellement bloqué, tout en exécutant un)
c'est à dire lorsque la fonction de thread n'est pas donner à l'appelant une chance de vous interrompre, vous êtes toujours bloqué.
Je ne suis pas sûr de ce que tu veux dire avec "going native" - il n'y a pas de support natif, sauf si vous êtes envoûté à
boost:threads
.Encore, j'utilise un mécanisme explicite. Vous avez à penser à avoir assez d'interruption de points de toute façon, pourquoi ne pas les rendre explicites? Le code supplémentaire est généralement marginale dans mon expérience, bien que vous devrez peut-être modifier certains attend à partir de l'objet unique à de multiples objets, qui - selon votre bibliothèque peut paraître plus laide.
On pourrait également tirer sur le "ne pas utiliser les exceptions pour le contrôle de flux", mais par rapport à déconner avec les threads, c'est juste une ligne directrice.
going native
, c'est à l'aide de fil::native_handle() pour accéder au thread de système d'exploitation, afin de mettre en œuvre le fil de l'interruption.interrupt
.Natif à l'aide de la poignée pour annuler un thread est une mauvaise option en C++ que vous devez détruire toutes les empiler les objets alloués. C'était la principale raison pour laquelle ils ne sont pas inclus une opération d'annulation.
Coup de pouce.Fil fournit une interruption mécanisme, qui doit unir sur toute attente primitive. Comme cela peut être coûteux comme un mécanisme général, le standard n'a pas inclus.
Vous devrez mettre en place par vous-même. Voir ma réponse ici à une question similaire sur la façon de mettre cela par vous-même. Pour compléter la solution d'une interruption doit être jeter en cas d'interruption est vrai et le fil doit attraper cette interruption et la finition.
Sa dangereux à mettre fin à une discussion, puisque vous n'avez aucun contrôle sur l'état de toutes les données-structures est travaillais à ce moment-là.
Si vous voulez interrompre un thread en cours d'exécution, vous devez mettre en place votre propre mécanisme. À mon humble avis, si vous avez besoin que votre conception n'est pas préparé pour plusieurs threads.
Si vous voulez juste à attendre qu'un thread pour finir, utiliser join() ou un avenir.
Il est dangereux de mettre fin à un thread de manière préventive en raison de l'état de l'ensemble du processus devient indéterminé après ce point. Le thread peut avoir acquis une section critique avant d'être interrompue. Cette section critique auront pas à être publié. Le tas pourrait devenir définitivement verrouillé, et ainsi de suite.
La
boost::thread::interrupt
solution fonctionne en demandant gentiment. Il ne interrompre un thread de faire quelque chose des thats interruptible, comme en attente d'un coup de pouce.Fil de la variable de condition, ou si le thread n'a une de ces choses après une interruption est appelée. Même alors, le fil n'est pas sans ménagement mis dans le hachoir à viande comme, par exemple, Win32 l'TerminateThread
fonction n'est, tout simplement, il induit une exception, qui, si vous avez été sage codeur et utilisé RAII partout, va nettoyer après lui-même et gracieusement à la sortie du fil.La mise en œuvre d'un do-it-yourself solution la plus logique, et il ne devrait vraiment pas être difficile de le faire. Vous aurez besoin d'une variable partagée-vous de lire/écrire de façon synchrone, en indiquant si le thread est en train d'être invité à se terminer, et votre thread lit régulièrement à partir de cette variable quand il est dans un état où il peut en toute sécurité être interrompu. Lorsque vous voulez interrompre un thread, il suffit d'écrire de manière synchrone à cette variable, puis vous rejoignez le fil. En supposant qu'il coopère de manière appropriée, il est à noter que la variable a été écrite et arrêter, résultant dans la fonction join n'est plus bloquant.
Si vous deviez aller à la maternelle, vous ne gagnerait rien en particulier; il vous suffit de jeter tous les avantages de la norme et de la croix-plate-forme de programmation orientée objet mécanisme de threading. Pour que votre code soit correct, le fil serait nécessaire d'arrêter la coopération, ce qui implique la communication décrit ci-dessus.
Voici mon humble mise en œuvre d'un thread canceller (pour C++0x).
J'espère que ce sera utile.
Mon implémentation des threads utilise le pimpl idiome, et dans l'Impl classe j'ai une version pour chaque OS que j'soutien et aussi un qui utilise le boost, donc je peux décider laquelle utiliser lors de la construction du projet.
J'ai décidé de faire deux classes: l'une est le Fil, qui n'a qu'à la base, le système d'exploitation fourni, services; et l'autre est SafeThread, qui hérite de Thread et a la méthode pour la collaboration interruption.
Thread a un terminate() méthode qui ne intrusive de la résiliation. C'est une méthode virtuelle qui est surchargé en SafeThread, où il signale un objet d'événement. Il y a un (statique) production() méthode qui le thread en cours d'exécution doit appeler de temps à autre; cette méthode vérifie si l'objet événement est signalé et, si oui, déclenche une exception interceptée à l'appelant du fil point d'entrée, ainsi, mettre fin à la discussion. Quand il le fait il signale un deuxième objet de l'événement pour que les demandeurs de résilier le() ne peut savoir que le thread a été arrêté en toute sécurité.
Pour les cas où il existe un risque de blocage, SafeThread::terminate() accepte un paramètre de délai d'attente. Si le délai expire, il appelle Thread::terminate(), donc dommage de tuer le thread. C'est une dernière ressource lorsque vous avez quelque chose que vous ne pouvez pas contrôler (comme une API tierce) ou dans des situations dans lesquelles un blocage fait plus de dégâts que les ressources des fuites et la comme.
Espère que ce sera utile pour votre décision et vous donnera une assez claire de l'image sur mon choix de conception. Si non, je peux poster des fragments de code à préciser si vous le souhaitez.
std::thread
etboost::thread
?Je suis d'accord avec cette décision. Par exemple, .NET permet d'interrompre toute thread de travail, et je n'ai jamais utiliser cette fonctionnalité et ne recommande pas de le faire pour tout programmeur professionnel. Je veux décider moi-même, lorsqu'un thread de travail peut être interrompu, et ce est la façon de le faire. C'est différent pour le matériel, les I/O, l'INTERFACE utilisateur et d'autres threads. Si un sujet peut être arrêté à n'importe quel endroit, ce qui peut causer pas défini le comportement du programme avec la gestion des ressources, opérations etc.