Linux: отзывчивость приложения и выбор ()

У меня есть консольное приложение C ++, которое использует open() [O_RDWR | O_NONBLOCK], write(), select(), read() а также close() работать с файлом устройства. Также ioctl() можно вызвать для отмены текущей операции. В любой момент времени только один пользователь может работать с устройством.

Мне нужно придумать класс C ++, имеющий сигналы libsigc ++, которые запускаются, когда данные поступают с устройства.

Проблема: при звонке select() приложение перестает отвечать на запросы, поскольку оно ожидает данных. Как сделать его отзывчивым — позвонив select() в рабочем потоке? Если так — как рабочий поток будет общаться с основным потоком? Может быть, я должен посмотреть в boost::asio?

1

Решение

Как сделать его отзывчивым — вызывая select () в рабочем потоке

ты можешь использовать DUP (), это дублирует ваши файловые дескрипторы … таким образом, вы можете переместить все операции чтения в другой поток. таким образом, ваш поток записи и поток обработки будут реагировать, даже когда поток read [select ()] находится в спящем режиме.

накладные расходы на передачу сигналов в libsigc ++ минимальны, поэтому я думаю, что вы можете встроить код в сам поток чтения. Слоты могут существовать в разных потоках, здесь вы будете получать свои сигналы …

Я думаю бережливость исходный код [полностью основанный на boost] может вас заинтересовать, хотя Thrift не использует libsigc ++.

0

Другие решения

Звучит так, как будто вы неправильно поняли select; цель select (или poll, epoll и т. д.) заключается не в «ожидании данных», а в «ожидании одного или нескольких событий, происходящих в последовательности файловых дескрипторов, или таймера, или сигнала, который должен быть подан».

Какая «отзывчивость» пропадает, пока вы находитесь в выбранном вами звонке? Вы сказали, что это консольное приложение, поэтому вы не говорите о цикле GUI, так что, вероятно, это связано с IO? Если это так, то вам нужно реорганизовать ваш выбор, чтобы ожидание данных, о которых вы говорите, было одним элементом; то есть, если вы используете select, создайте FD_SET из ВСЕХ файловых / сокетных дескрипторов (а stdin и stdout — файловые дескрипторы), для которых вы хотите ожидать ввода.

Или создайте цикл, который периодически вызывает «select» с коротким таймаутом для / test / для любого ожидающего ввода и пытается только прочитать его, когда select говорит вам, что есть что прочитать.

0

Похоже, у вас есть производитель-потребитель проблема стиля Существуют различные способы реализации решения этой проблемы, но большинство людей в наши дни склонны использовать переменная условия основанные подходы (см. это Пример на основе C ++ 11).

Существует также ряд шаблонов проектирования, которые при реализации могут помочь решить проблему параллелизма, например:

Полусинхронизация / полусинхронизация

  • Шаблон стиля производитель-потребитель, который вводит очередь между асинхронным уровнем, который заполняет очередь событиями, и синхронным уровнем, который обрабатывает эти события.

Лидер / Последователи

  • Несколько потоков по очереди обрабатывают события
  • Связанное обсуждение доступно Вот.
0
По вопросам рекламы [email protected]