У epoll есть проблемы с потоками?

Это продолжение вопроса 14221339.

У меня есть пул потоков, который работает внутри epoll_wait() петля.

Внешний поток вызывает epoll_ctl() и добавляет сокет слушателя с

(EPOLLET | EPOLLONESHOT | EPOLLIN),

Когда пул потоков имеет только один поток, он периодически не может получить EPOLLIN событие для первой (и единственной) попытки подключения. Если я увеличу пул потоков до двух, он почти всегда не получит EPOLLIN событие.

Насколько я понимаю, API epoll является поточно-ориентированным, но, похоже, это наблюдение указывает на обратное.

1 ответ

При семантике, инициируемой ребром, неправильная последовательность вызовов может привести к состоянию гонки. Здесь задействованы три системных вызова:

  1. epoll_ctl() для активации уведомлений (и повторной активации, если используется EPOLLONESHOT).
  2. epoll_wait () для получения уведомлений.
  3. системный ввод: чтение ()/recv()/accept() в цикле до появления ошибки EAGAIN.

Если выполняется (многократно) в этом порядке, возможна гонка между #3 и #1: когда событие ввода в ядре происходит после того, как EAGAIN был возвращен, но до того, как epoll_ctl() может быть задействована. Как правило, повторную активацию необходимо выполнить до ввода-вывода.

  1. epoll_ctl() для активации уведомлений (и повторной активации, если используется EPOLLONESHOT).
  2. системный ввод: чтение ()/recv()/accept() в цикле до появления ошибки EAGAIN.
  3. epoll_wait () для получения уведомлений.

(Очевидно, что ввод / вывод должен быть неблокирующим.)

Другие вопросы по тегам