Обратные вызовы и задержки в цикле выбора / опроса - PullRequest
0 голосов
/ 26 декабря 2009

Можно использовать опрос / выбор при написании сервера, который может обслуживать несколько клиентов в одном потоке. выберите и опросите, однако для работы нужен дескриптор файла. По этой причине я не уверен, как выполнять простые асинхронные операции, такие как реализация простого обратного вызова для прерывания длительной операции или отложенного обратного вызова без выхода из цикла выбора / опроса. Как можно это сделать? В идеале я хотел бы сделать это, не прибегая к созданию новых тем.

В двух словах, я ищу механизм, с помощью которого я могу выполнять ВСЕ асинхронные операции. Windows WaitForMultipleObjects или Symbian TRequestStatus кажется гораздо более подходящим для обобщенных асинхронных операций.

Ответы [ 4 ]

1 голос
/ 26 декабря 2009

Для произвольных обратных вызовов следует поддерживать канал POSIX (см. Pipe (2)). Если вы хотите сделать отложенный вызов, напишите структуру, состоящую из указателя функции и необязательного указателя контекста, в конец записи. Конец чтения - просто еще один вход для выбора. Если он выбирает readable, прочитайте ту же структуру и вызовите функцию с контекстом в качестве аргумента.

Для обратных вызовов по расписанию ведите список в порядке своевременности. Записи в списке являются структурами, например, {срок выполнения (как интервал с момента предыдущего обратного вызова); указатель на функцию; необязательный указатель контекста}. Если этот список пуст, заблокируйте навсегда в select (). В противном случае, тайм-аут, когда должно произойти первое событие. Перед каждым вызовом для выбора пересчитайте время первого события.

Скрыть детали за разумным интерфейсом.

0 голосов
/ 26 декабря 2009

Вы можете воспользоваться тайм-аутом select () или poll (), чтобы периодически выполнять фоновые операции:

for ( ;; ) {
   ...
   int fds = select(<fds and timeout>);
   if (fds < 0) {
       <error occured>
   } else if if (fds == 0) {
       <handle timeout, do some background work.>
   } else {
       <handle the active file descriptors>
   }
 }
0 голосов
/ 26 декабря 2009

Для немедленного обратного вызова с использованием цикла выбора можно использовать один из специальных файлов, таких как / dev / zero, которые всегда активны. Это позволит выбрать выход в ближайшее время, но также позволит активировать другие файлы.

Для временных задержек я могу только использовать тайм-аут при выборе.

Оба из вышеперечисленных чувствуют себя не очень хорошо, поэтому, пожалуйста, пришлите лучшие ответы.

0 голосов
/ 26 декабря 2009

select() и poll() являются системными вызовами - это означает, что ваша программа вызывает ядро ​​ОС, чтобы сделать что-то, и ваша программа ничего не может сделать, ожидая возврата из ядра, если вы не используете другой поток.

Хотя select() и poll() используются для асинхронного ввода-вывода, эти функции (системные вызовы) не являются асинхронными - они будут блокироваться (если вы не укажете тайм-аут), пока не произойдет что-то с дескриптором, который вы смотрите.

Лучшей стратегией было бы время от времени проверять дескрипторы (указав небольшое значение тайм-аута), и, если ничего не происходит, делать то, что вы хотите делать во время простоя, в противном случае обрабатывать ввод / вывод.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...