Как прочитать несколько дескрипторов файлов, используя epoll_select с epollet?

StackOverflow https://stackoverflow.com/questions/4003804

  •  25-09-2019
  •  | 
  •  

Вопрос

Человек Epoll:

The suggested way to use epoll as an edge-triggered (EPOLLET) interface is as follows:
    i   with nonblocking file descriptors; and
    ii  by waiting for an event only after read(2) or write(2) return EAGAIN.

Представьте, что у нас есть два FDS: первый пассивный, данные доступны только иногда, второй активен, данные только иногда не доступны.

Epoll_wait вернул, что мы можем прочитать оба. Мы читаем {первое, чем второе} в цикле (без вызовов в epoll_wait из-за него может внезапно блокировать, пока данные все еще доступны).

Теперь первый файловый дескриптор вернул EAGAIN на чтение.

Что делать?

  1. Если мы продолжим чтение второй FD в цикле (без вызовов в epoll_wait), мы можем пропустить, что данные стали доступными на первом FD. Он просто прочитал и читает и читает без оркестра.
  2. Если мы будем «проконсультироваться» с EPOLL_WAIT перед каждым чтением со второго FD, epoll_wait может внезапно блокировать из-за того, что ничего не изменилось с предыдущего вызова (данные, все еще не доступные на первом FD и все еще доступны на втором FD).

Как продолжить обработку второго FD, но не забывая о первой FD?

Обновлять: Найдено еще одна вещь: Man Epoll_Wait:

while specifying timeout equal to zero makes epoll_wait() to return immediately even if no events are available

С этим я могу перечислить события для FDS, даже если нет событий.

Это было полезно?

Решение

Если FD2 постоянно читается, вы можете учитывать, что EPOLL не подходит для него. Возможно, стоит вращаться с нити, чтобы просто сидеть и прочитать его.

В противном случае прочитайте FD2 в цикле, пока он не будет сливаться, а в цикле не пытается прочитать FD1 один раз каждый x раз. Если FD1 имеет данные, прочитайте его. Если нет, вы просто получите EAGAIN, сбросьте счетчик X и вернитесь к чтению FD2. Когда оба сливаются, вы вернулись в epoll_wait.

Что-то типа:

count = 1;

while (true)
{
   read fd2;

   if (EAGAIN)
       break;
   else
       process data;

   count--;

   if (! count)
   {  
       while (true)
       {
           read fd1;

           if (EAGAIN)
               count = 10;
               break;
           else
               process data;
       }
   }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top