Comment effectuer une lecture non bloquante en utilisant asio?
J'essaie d'utiliser boost::asio à lire et à écrire à partir d'un périphérique sur un port série. Boost::asio:read() et boost::asio::serial_port::read_some() bloc quand il n'y a rien à lire. Au lieu de cela, je voudrais détecter cette condition et d'écrire une commande pour le port de démarrer l'appareil.
Comment puis-je détecter qu'aucune donnée n'est disponible?
Si nécessaire, je peux tout faire de manière asynchrone, je voudrais juste éviter le supplément de complexité, si je peux.
source d'informationauteur Joe Ludwig
Vous devez vous connecter pour publier un commentaire.
Vous avez quelques options, en fait. Vous pouvez soit utiliser le port série intégré dans
async_read_some
de la fonction, ou vous pouvez utiliser la fonctionboost::asio::async_read
(ouasync_read_some
).Vous devez toujours exécuter dans la situation où vous êtes effectivement en "bloqué", comme aucune de ces va appeler la fonction de rappel, à moins que (1) les données ont été lues ou (2) une erreur se produit. Pour contourner ce problème, vous devrez peut-être utiliser un
deadline_timer
objet de définir un délai d'attente. Si le délai d'extinction des incendies d'abord, aucune donnée n'était disponible. Sinon, vous devrez lire les données.La complexité n'est pas vraiment si mauvais que ça. Vous vous retrouverez avec deux rappels avec un comportement similaire. Si la "lecture" ou le "délai d'attente" de rappel se déclenche avec une erreur, vous savez, c'est la course perdant. Si l'un des deux feux sans une erreur, alors vous savez que c'est le vainqueur de la course, et vous devez annuler l'autre appel). Dans l'endroit où vous avez eu votre appel de blocage à
read_some
vous aurez maintenant un appel àio_svc.run()
. Votre fonction sera encore bloquer comme avant, quand il appellerun
mais cette fois vous avez le contrôle de la durée.Voici un exemple:
Qui devrait vous obtenir a commencé avec seulement quelques modifications ici et là pour répondre à vos besoins spécifiques. J'espère que cela aide!
Une autre remarque: Pas de supplément de discussions ont été nécessaires pour gérer les rappels. Tout est géré à l'intérieur de l'appel à
run()
. Vous ne savez pas si vous étiez déjà au courant de cela...Vous devez utiliser le libre-fonction asio::async_read.
Sa en fait beaucoup plus simple que les réponses ici implicite, et vous pouvez le faire de manière synchrone:
Supposons que votre blocage de lire quelque chose comme:
Alors que vous pouvez la remplacer avec
Vous utilisez l'alternative surchargé forme de receive_from à laquelle presque tous les envoyer/recevoir méthodes ont. Malheureusement, ils prennent un argument flags mais 0 semble bien fonctionner.