6
votes

Interruption Boost :: Asio Synchronous Lire?

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".

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: waitformultiplateObjects qui ferait exactement ce que je veux.

Comment pourrais-je obtenir un effet similaire avec Boost?


0 commentaires

5 Réponses :


2
votes

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.

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.

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.


0 commentaires

2
votes

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 async_read ou async_write est de fermer la prise.

  • [destructeur] Notez que nous voulons détruire
  • [destructeur] Fermer la prise
  • [Destructor] Attendez les gestionnaires d'achèvement

  • [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.

  • [achèvement] retour immédiatement.

    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.

    Ceci était assez subtile que nous construisons une enveloppe d'achèvement (similaire à io_service :: Strand juste pour supporter de manière synchrone annulant de manière synchrone tous les rappels d'achèvement en attente.


0 commentaires

1
votes

meilleur moyen est de créer un socketpair () , (quoi que ce soit dans boost :: ASIO 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.

Le fil doit ensuite se fermer volontairement.

Le tacouréat du fil devrait dans son destructeur, a les suivants: xxx


0 commentaires

-1
votes

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.


0 commentaires

0
votes
boost::system::error_code _error_code;
client_socket_->shutdown(client_socket_->shutdown_both, _error_code);
Above code help me close sync read immediately.

0 commentaires