Разблокировать синхронное чтение на boost :: asio :: serial_port - PullRequest
7 голосов
/ 08 февраля 2012

У меня есть boost::thread, который выполняет синхронные чтения на boost::asio::serial_port. Когда я уничтожаю экземпляр класса, который содержит оба, я хочу, чтобы поток завершился изящно, даже если он заблокирован в вызове чтения. Как я могу это сделать?

Глядя на документы , я попытался cancel, но он работает только для асинхронного чтения / записи. Затем я попытался close, но у меня возникло исключение, и это было не то, от чего можно оправиться. Возможно, используя send_break или native_handle? (это Windows и переносимость не критична)

Обновление : Я также попытался stop io_service, который я передал конструктору объекта последовательного порта, но read не был разблокирован.

Редактировать : Исключение на самом деле "перехватывается", но я бы не хотел помещать блок try / catch внутри деструктора, а рефакторинг кода для выполнения процесса выключения вне деструктора вызывал бы лоты изменений в верхних слоях. Так что я бы пошел на это решение, только если кто-то из авторитетов Boost сказал, что другого пути нет.

Ответы [ 2 ]

5 голосов
/ 09 февраля 2012

Невозможно разблокировать синхронное чтение, как вы просите.

Существует два варианта:

  • close / shutdown порт и перехват исключения, который был поднят
  • , используя асинхронные операции чтения и cancel их, когда вы закрываете свое приложение

Первое, конечно, не очень хорошая идея, потому что вы не можете различитьЗавершение приложения из-за ошибки.

1 голос
/ 11 февраля 2012

При закрытии вы говорите, что получили исключение, которое «было не тем, от которого вы можете оправиться».

Что это значит?

Решение, похоже, состоит в том, чтобы поймать исключение. Почему ты не можешь этого сделать?

Для случая, когда вы хотите различить ошибку и завершение программы, установите флажок завершения программы перед закрытием. В обработчике исключений (catch) отметьте флажок. Если установлено, обрабатывать как завершение программы, иначе обрабатывать как ошибку.

Вы говорите, что не хотите помещать блок try / catch внутри деструктора. Это кажется странным предубеждением для меня, но хорошо, есть и другие способы.

  1. Вы можете разрешить исключению распространяться до самого верхнего блока catch, который окружает весь ваш код, и обрабатывать его там. (Конечно, у вас есть такой блок try / catch, защищающий все ваше приложение: -)

  2. Возможны и другие способы ... но босс только что упал на

...