2012-01-01 4 views
4

Если я являюсь epoll_wait() на прослушивающем сокете и, когда epoll_wait() возвращает указание о его активности (в этом случае соединение, ожидающее принятия() ed), то если вызов accept() завершился с ошибкой с errno = EINTR, будет ли epoll_wait() указывать на то, что то же самое соединение ожидает в гнезде для прослушивания при следующем его возврате?accept() прерван по сигналу и epoll_wait()

т.е. мне нужно сделать что-то вдоль линий:

while(1){ 
    epoll_wait(epfd, &events, maxevents, timeout); 
    if (events.data.fd == listener){ 
     connsock = accept(listener, &addr, &addrlen); 
     while (connsock != -1){ 
      if (errno == EINTR){ 
       accept(listener, &addr, &addrlen); 
       } 
      } 
     } 
    } 

для того, чтобы убедиться, что соединение получает принято, или это будет работать и по-прежнему убедитесь, что соединение, для которого принимает() был прерван сигналом получает принято:

while(1){ 
    epoll_wait(epfd, &events, maxevents, timeout); 
    if (events.data.fd == listener){ 
     connsock = accept(listener, &addr, &addrlen); 
     } 
    } 

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

Очевидно, что в обоих этих примерах я делаю некоторые предположения (что, например, только одно событие на одном сокете возвращается в данном вызове epoll_wait) и исключает проверку ошибок (за исключением EINTR на accept(), так как здесь все дело), ​​чтобы упростить вещи

ответ

2

В этом разница между запуском и триггером уровня. Используйте триггер уровня запуска, значение по умолчанию, и вам не нужно беспокоиться об этом.

Компромисс с триггером уровня состоит в том, что один поток не может обрабатывать обнаруженное событие, в то время как другой поток возвращается к вызову epoll_wait - он снова обнаружил бы одно и то же событие. Но в большинстве случаев вам все равно не нужно это делать, и компромисс между его невозможностью проиграть событие стоит того.

+0

Вы все равно не проиграете мероприятие. Пока ожидающее соединение не будет успешно принято или не будет выполнено, оно останется в резервном ядре ядра и немедленно вызовет epoll_wait при следующем опросе. –

+2

@JasonCoco Не в режиме с красным фронтом. Вся точка режима, вызванного краем, заключается в том, чтобы сделать это не так, чтобы один поток мог обрабатывать событие, а другой поток вызывал «epoll_wait» и, если нет * новых * событий, блоки. (Level-triggered - значение по умолчанию). Можно ли выбрать новое событие для повторного оружия через «EPOLLONESHOT». –

+0

Спасибо, я ценю ответ. Таким образом, разницу между срабатыванием уровня и срабатыванием по краю можно рассматривать как разницу между «пребыванием в определенном состоянии» и «изменением на определенное состояние с момента последнего просмотра»? Вот что я понял из чтения страниц руководства, но у меня никогда не было подтверждения, что мое понимание верное. –

Смежные вопросы