Эполл с запуском по краю, одним выстрелом и многопоточностью
Это вопрос относительно этого ответа: /questions/32562164/u-epoll-est-problemyi-s-potokami/32562175#32562175 (прокомментирую это, но вновь созданные учетные записи, очевидно, не могут, извините за шум. Ресурсы по epollet/ многопоточности найти трудно..)
Он предлагает использовать epoll следующим образом:
epoll_ctl()
активировать уведомления (и активировать, еслиEPOLLONESHOT
используется).- вход системы:
read()
/recv()
/accept()
в цикле до ошибкиEAGAIN
, epoll_wait()
получать уведомления.
Но при условии, что в epoll_wait()
на том же самом epollfd, не рискнул бы ли это вызвать пробуждение другого потока на том же самом fd, если он получил больше данных до того, как вы закончили чтение (например, в результате два потока обрабатывают один и тот же fd)?
Даже если вы перевернете вещи и read()
до EAGAIN
, epoll_ctl()
а затем позвоните read()
еще раз, чтобы проверить, что все еще ничего (чтобы избежать гонки, где вы получите что-то между последним чтением и epoll_ctl()
)...
НО до сих пор нет никаких гарантий, что вы не получили бы что-то после epoll_ctl()
и будет как последний read()
проверь и другой поток проснулся, снова работая на тот же FD...
Я предполагаю, что наличие блокировки для fd было бы приемлемым решением, но является ли это "одобренным" использованием epoll в режиме запуска по фронту с несколькими потоками, опрашивающими один и тот же epollfd?
1 ответ
Да, вам все еще нужно сделать правильную блокировку, чтобы защититься от тех случаев, которые вы описываете - и использование блокировки на fd является наиболее разумным подходом для этого.