Эполл, управляемый одним выстрелом * на уровне * (): подразумевает ли EPOLLONESHOT EPOLLET?
Можно ли использовать epoll
в режиме "один выстрел"?
Я не мог найти информацию об этом, когда я искал; Кажется, что все используют режим с триггером.
2 ответа
Когда EPOLLONESHOT
флаг выбран, и вы извлекли событие для сокета, тогда сокет не будет удален из epoll, как многие думают, но его события отключены. Вы можете включить их снова, используя epoll_ctl
/ EPOLL_CTL_MOD
,
Пример случая, когда EPOLLONESHOT
поведение пригодится, когда вы прочитаете доступные данные из сокета в буфер. Этот буфер будет очищен независимо, но до тех пор, пока он не будет пустым, вы должны отключить события сокета, даже если в сокете есть дополнительные данные. Затем, после того как буфер будет использован и очищен, вы можете снова включить сокет.
Разница между "однократным" поведением, инициируемым краем и уровнем, проявляется только при повторном включении сокета. Пример:
- Сокет получает данные 7K (сейчас они хранятся в буфере ядра)
- Вы ждете входное событие, затем события сокета отключаются из-за EPOLLONESHOT.
- Вы читаете 4K в буфер уровня приложения.
- Позже буфер приложения используется и очищается. Вы снова включаете сокет с
epoll_ctl
/EPOLL_CTL_MOD
,
ЭПОЛЛОНЕШОТ, управляемый уровнем:
- Так как данные 3K все еще присутствуют в буферах ядра, событие инициируется снова.
ЭПОЛЛОНЕШОТ, управляемый краем:
- Это не вызовет событие снова для доступных данных. Вы должны проверить это, читая и ожидая
EAGAIN
/EWOULDBLOCK
,
Если вы хотите, чтобы epoll прекратил прослушивание через сокет, вам следует использовать EPOLLONESHOT. Если вы используете EPOLLONESHOT, вам придется добавить сокет обратно в epoll после сигналов epoll на этом сокете. Таким образом, EPOLLONESHOT не является EPOLLET. Вы можете использовать EPOLLONESHOT без EPOLLET, но это может быть неэффективно. Если вы используете оба флага, то вам придется использовать неблокирующие сокеты и добавить сокет в epoll только один раз в recv и отправить return с ошибкой EAGAIN. Пожалуйста, обратитесь к странице справки для деталей.