У меня есть консольное приложение C ++, которое использует open() [O_RDWR | O_NONBLOCK]
, write()
, select()
, read()
а также close()
работать с файлом устройства. Также ioctl()
можно вызвать для отмены текущей операции. В любой момент времени только один пользователь может работать с устройством.
Мне нужно придумать класс C ++, имеющий сигналы libsigc ++, которые запускаются, когда данные поступают с устройства.
Проблема: при звонке select()
приложение перестает отвечать на запросы, поскольку оно ожидает данных. Как сделать его отзывчивым — позвонив select()
в рабочем потоке? Если так — как рабочий поток будет общаться с основным потоком? Может быть, я должен посмотреть в boost::asio
?
Как сделать его отзывчивым — вызывая select () в рабочем потоке
ты можешь использовать DUP (), это дублирует ваши файловые дескрипторы … таким образом, вы можете переместить все операции чтения в другой поток. таким образом, ваш поток записи и поток обработки будут реагировать, даже когда поток read [select ()] находится в спящем режиме.
накладные расходы на передачу сигналов в libsigc ++ минимальны, поэтому я думаю, что вы можете встроить код в сам поток чтения. Слоты могут существовать в разных потоках, здесь вы будете получать свои сигналы …
Я думаю бережливость исходный код [полностью основанный на boost] может вас заинтересовать, хотя Thrift не использует libsigc ++.
Звучит так, как будто вы неправильно поняли select; цель select (или poll, epoll и т. д.) заключается не в «ожидании данных», а в «ожидании одного или нескольких событий, происходящих в последовательности файловых дескрипторов, или таймера, или сигнала, который должен быть подан».
Какая «отзывчивость» пропадает, пока вы находитесь в выбранном вами звонке? Вы сказали, что это консольное приложение, поэтому вы не говорите о цикле GUI, так что, вероятно, это связано с IO? Если это так, то вам нужно реорганизовать ваш выбор, чтобы ожидание данных, о которых вы говорите, было одним элементом; то есть, если вы используете select, создайте FD_SET из ВСЕХ файловых / сокетных дескрипторов (а stdin и stdout — файловые дескрипторы), для которых вы хотите ожидать ввода.
Или создайте цикл, который периодически вызывает «select» с коротким таймаутом для / test / для любого ожидающего ввода и пытается только прочитать его, когда select говорит вам, что есть что прочитать.
Похоже, у вас есть производитель-потребитель проблема стиля Существуют различные способы реализации решения этой проблемы, но большинство людей в наши дни склонны использовать переменная условия основанные подходы (см. это Пример на основе C ++ 11).
Существует также ряд шаблонов проектирования, которые при реализации могут помочь решить проблему параллелизма, например:
Полусинхронизация / полусинхронизация