poll (2) не очищает очередь событий - PullRequest
8 голосов
/ 11 июня 2010

Я использую Linux в качестве моей платформы программирования.Я использую poll(2), чтобы узнать, инициирует ли мое устройство событие.

Первый вызов poll в порядке;он блокирует и ждет события.Но при втором вызове функции poll он вернется;но он фиксирует событие.Ниже мой код.

ret = poll( fds, 1, 2000); //2 secs timeout

if( fds[0].revents & POLLIN && ret > 0)
{
   printf("event occur\n");
}

Кажется, что очередь / буфер не пуст.Я просто предполагаю.

Как вы думаете, в чем проблема?

Спасибо.

Ответы [ 4 ]

11 голосов
/ 11 июня 2010

Очевидно, что если вы опрашиваете входящие данные, вы должны использовать доступные данные (вызывая read ()), или они все еще будут там, и опрос немедленно вернется. Симметрично никакая операция действительно не требуется для POLLOUT, но обычно вы хотите вызвать следующую запись () как можно скорее. Так что, как правило, POLLIN -> читать, POLLOUT -> писать.

Вы должны также сбросить свою структуру pollfd перед повторным вызовом poll.

fds[0].fd = sck;
fds[0].events = POLLIN;
fds[0].revents = 0;
ret = poll( fds, 1, 2000); //2 secs timeout

if( fds[0].revents & POLLIN && ret > 0)
{
   printf("event occur\n");
}

Если вы не сбрасываете его каждый раз, мусор из предыдущего вызова может изменить поведение опроса (ну, не совсем, это просто проблема переносимости).

В рабочем коде вы также должны проверить возвращаемое значение, так как опрос мог быть прерван по другой причине, чем ожидаемое событие (например, сигнал). Затем вы обычно хотите вызвать его снова вместо чтения данных, которые недоступны (в качестве напоминания возвращаемое значение опроса - это число событий, 0 тайм-аут, -1 некоторая ошибка, номер которой указан в ошибке).

Могут также возникнуть ошибки в дескрипторах файлов, предоставленных для опроса. Они не будут делать опрос, возвращающий ошибку, но установят POLLERR, POLLHUP или POLLNVAL в поле revent структуры pollfd для этого файлового дескриптора. Если эти события установлены, при вызове read вернет код ошибки, который вы можете проверить.

5 голосов
/ 11 июня 2010

если у вас есть событие POLLIN, что означает «Есть данные для чтения» - вызываете ли вы какую-нибудь функцию read() на вашем fd перед poll() повторным вызовом?

4 голосов
/ 11 июня 2010

poll дает вам событие, если есть данные / события для чтения / ошибки / когда вы можете написать.

Если вы получаете событие, говорящее «есть данные для чтения», и вы ничего не читаете - все равно будут «данные для чтения» при следующем вызове poll и вы получите другое событие.

4 голосов
/ 11 июня 2010

Рекомендуется проверять POLLHUP или POLLNVAL перед чтением дескриптора файла. Тем не менее, я считаю, что read() просто потерпит неудачу, если это так, , если не будет опрошен дескриптор файла, который должен блокироваться в течение длительных периодов, например, модем . В этом случае вы зависаете (в зависимости от того, что вы передали open()).

Вы, вероятно, не:

  • Чтение события FD вообще до следующего poll(), или,
  • Чтение всех доступных данных.

Если вы инициализировали массив struct pollfd до вызова poll(), не должно быть никакого «мусора», о котором можно было бы говорить.

Тем не менее, это, вероятно, также хорошая идея, чтобы проверить и убедиться, что есть что-то, что стоит потрудиться read() сделать перед вызовом.

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