J'utilise des sockets synchrones ASIO pour lire des données sur TCP à partir d'un fil d'arrière-plan. Ceci est encapsulé dans une classe "serveur". P>
Cependant, je veux que le fil quitte lorsque le destructeur de cette classe est appelé.
Le problème est qu'un appel à l'une des fonctions de lecture bloque, le thread ne peut donc pas être terminé facilement. Dans Win32, il y a une API pour cela: Comment pourrais-je obtenir un effet similaire avec Boost? P> waitformultiplateObjects code> qui ferait exactement ce que je veux. P>
5 Réponses :
Dans notre application, nous définissons la condition "Termination", puis utilisez une connexion auto-attachée au port que le thread l'écoute de sorte qu'il se réveille, remarque la condition de terminaison et la résiliation. P>
Vous pouvez également vérifier la mise en oeuvre de boost - si elles ne font que lire une lecture simple sur la prise (c'est-à-dire que vous n'utilisez pas quelque chose comme WaitFormultiPleObjects interne eux-mêmes), vous pouvez probablement en conclure qu'il n'y a rien à débloquer simplement et de débloquer simplement la fil. S'ils attendent sur plusieurs objets (ou port d'achèvement), vous pouvez creuser pour voir si la capacité de réveiller le fil de blocage est exposée à l'extérieur. P>
Enfin, vous pourriez tuer le fil - mais vous devrez sortir de votre choix pour le faire et comprendre les conséquences, telles que des ressources pendantes ou fuies. Si vous vous arrêtez, cela peut ne pas être une préoccupation, en fonction de ce que cela faisait. P>
Je n'ai trouvé aucun moyen facile de le faire. Soi-disant, il existe des moyens d'annuler Win32 IOCP, mais cela ne fonctionne pas bien sur Windows XP. MS a correctement réparais pour Windows Vista et 7. L'approche recommandée pour annuler ASIO [Destructor] Attendez les gestionnaires d'achèvement P> Li>
[Achèvement] Si vous démolissez et nous avons simplement échoué car la prise fermée, informez le destructeur que les gestionnaires d'achèvement sont effectués. P> LI>
Soyez prudent si vous choisissez de la mettre en œuvre. La fermeture de la prise est assez simple. «Attendez que les gestionnaires d'achèvement» soient énormes sous-estimations. Il existe plusieurs cas d'angle subtils et des conditions de course pouvant survenir lorsque le fil du serveur et son destructeur interagissent. P>
Ceci était assez subtile que nous construisons une enveloppe d'achèvement (similaire à async_read code> ou
async_write code> est de fermer la prise. P>
io_service :: Strand code> juste pour supporter de manière synchrone annulant de manière synchrone tous les rappels d'achèvement en attente. P>
meilleur moyen est de créer un Le fil doit ensuite se fermer volontairement. P> Le tacouréat du fil devrait dans son destructeur, a les suivants: p> socketpair () code>, (quoi que ce soit dans
boost :: ASIO CODE> Parlance), ajoutez la fin du lecteur à la boucle d'événement, puis fermez L'écrivain finit. Vous serez réveillé immédiatement avec un événement EOF sur cette prise.
utiliser socket.cancel (); mettre fin à toutes les opérations asynchrones actuelles qui bloquent sur une prise. Les prises client peuvent avoir besoin d'être tuées dans une boucle. Je n'ai jamais eu à fermer le serveur de cette façon, mais vous pouvez utiliser Shared_From_This () et exécuter Annuler () / Fermer () dans une boucle de la même manière que l'exemple de chat de boost async_writes à tous les clients. P>
boost::system::error_code _error_code; client_socket_->shutdown(client_socket_->shutdown_both, _error_code); Above code help me close sync read immediately.