Эполл с запуском по краю, одним выстрелом и многопоточностью

Это вопрос относительно этого ответа: /questions/32562164/u-epoll-est-problemyi-s-potokami/32562175#32562175 (прокомментирую это, но вновь созданные учетные записи, очевидно, не могут, извините за шум. Ресурсы по epollet/ многопоточности найти трудно..)

Он предлагает использовать epoll следующим образом:

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

Но при условии, что в epoll_wait() на том же самом epollfd, не рискнул бы ли это вызвать пробуждение другого потока на том же самом fd, если он получил больше данных до того, как вы закончили чтение (например, в результате два потока обрабатывают один и тот же fd)?

Даже если вы перевернете вещи и read() до EAGAIN, epoll_ctl() а затем позвоните read() еще раз, чтобы проверить, что все еще ничего (чтобы избежать гонки, где вы получите что-то между последним чтением и epoll_ctl())...

НО до сих пор нет никаких гарантий, что вы не получили бы что-то после epoll_ctl() и будет как последний read() проверь и другой поток проснулся, снова работая на тот же FD...

Я предполагаю, что наличие блокировки для fd было бы приемлемым решением, но является ли это "одобренным" использованием epoll в режиме запуска по фронту с несколькими потоками, опрашивающими один и тот же epollfd?

1 ответ

Решение

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

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