epoll_wait() возвращает EINTR бесконечно
У меня есть нить, ответственная за опрос различных FDS. Я использую epoll_wait с установленным временем ожидания. Ниже приведен фрагмент кода:
do {
n = epoll_wait(epollFd, eventsList, eventsTotal, timeoutMS);
}
while ((n<0) && (errno == EINTR));
Память eventsList содержит timerfd, signalfd и сокет fd.
Поток работает хорошо и обрабатывает события таймера, события открытия / чтения / записи / закрытия сокета и определяемые пользователем события сигнала.
Но бывают случаи, когда поток входит в бесконечный цикл do-while, поскольку errno всегда возвращает EINTR.
Верхняя часть потока показывает статус сна. strace показывает, что он вызывает epoll_wait() в цикле.
Так что может пойти не так, как я использую общепринятый способ обработки epoll_wait & EINTR? Может ли быть что-то не так с чтением / записью / закрытием сокета, что может вызвать вышеуказанную проблему? Или с помощью timerfd?
Обновление: вывод strace -p:
epoll_wait(8, {}, 8192, 10) = 0
epoll_wait(8, {}, 8192, 10) = 0
epoll_wait(8, {}, 8192, 10) = 0
epoll_wait(8, {}, 8192, 10) = 0
Затем я взял gcore и попытался вернуть errno с помощью epoll_wait(). Это 4 (EINTR)
1 ответ
Было бы более полезно, если бы вы показали нам хотя бы фрагмент из strace
выход. По крайней мере, это скажет нам, какое прерывание получено.
Без этой информации я не могу сказать вам, что не так с вашей программой. Я могу, однако, рассказать вам, как это выяснить.
Во-первых, посмотрите на вывод strace. Он скажет вам, какой сигнал получает процесс.
Затем посмотрите на обработчик сигнала для этого сигнала. Если у вас его нет, зарегистрируйте его. Убедитесь, что вы используете sigaction
и не signal
сделать это. Кроме того, убедитесь, что вы используете более новую sa_sigaction
формат функции.
В этом формате ваш обработчик сигнала получает информацию о том, кто отправил этот сигнал. Это включает в себя PID отправителя, если это таймер, идентификатор таймера и т. Д. Используйте эту информацию, чтобы определить, откуда поступает сигнал.