Сигналы ввода / вывода и обработчики - PullRequest
0 голосов
/ 10 августа 2009

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

Я знаю об использовании fcntl (), чтобы файловые дескрипторы вызывали SIGIO, но, скажем так, все не так просто. У меня есть объект A с сокетом a и объект B с сокетом b. Сокет a получает новый пакет и, следовательно, вызывает SIGIO. Однако это влияет только на объект A и не имеет ничего общего с объектом B.

Как я могу гарантировать, что определенная функция вызывается, когда конкретный порт получает пакет?

Ответы [ 3 ]

2 голосов
/ 10 августа 2009

Я рекомендую использовать библиотеку Boost.ASIO . Он предназначен для асинхронного ввода-вывода.

1 голос
/ 11 августа 2009

Как я могу гарантировать, что определенная функция вызывается, когда конкретный порт получает пакет?

(Под «портом» здесь, я полагаю, вы метонимно подразумеваете дескриптор файла S_IFSOCK , который представляет ваш сокет UDP.)

У вас есть множество общих опций , доступных для приложений, управляемых вводом / выводом: блокировка потоков считывателя, мультиплексирование с select (2) или poll (2) или аналогичный, запрашивающий уведомление о сигнале (особенно с использованием очередей сигналов в реальном времени и дополнительной информации в обработчике SA_SIGINFO), асинхронный ввод-вывод через aio_read (2) . См. здесь для краткого обзора.

Еще лучше, использовать стороннюю библиотеку , которая абстрагирует эти грязные детали, как в другом месте упомянутое Boost.ASIO или libevent .

Сокет a получает новый пакет и, следовательно, вызывает SIGIO. Однако это влияет только на объект А и не имеет ничего общего с объектом Б.

Ну, не совсем. Сигналы доставляются («обрабатываются») потоку внутри процесса, иногда потоку по вашему выбору, и в этом смысле напрямую не влияют ни на объект A, ни на объект B. :) Возможно, вы имеете в виду, что обычный SIGIO не может отличить «данные готовы» на сокете A от того, что на сокете B?

Если это так, то не использует простой SIGIO. В Linux достаточно fcntl (F_SETSIG) и обработчик SA_SIGINFO с сигналами в реальном времени, чтобы отличить один готовый fd от другого.

1 голос
/ 10 августа 2009

Boost.Signals или Boost.Signals2 (поточно-ориентированная версия) могут быть вам полезны.

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