epoll_wait() returns EINTR 无限
epoll_wait() returns EINTR infinitely
我有一个线程负责轮询各种fds。我正在使用 epoll_wait 并设置了超时。
以下是代码片段:
do {
n = epoll_wait(epollFd, eventsList, eventsTotal, timeoutMS);
}
while ((n<0) && (errno == EINTR));
eventsList内存包含timerfd、signalfd和socket fd。
该线程运行良好并处理定时器事件、套接字open/read/write/close 事件和用户定义的信号事件。
但有时线程会进入无限 do-while 循环,因为 errno 总是 returns EINTR.
Top -H 线程显示状态为睡眠。 strace 显示它正在调用
epoll_wait() 循环。
所以我使用的是广为接受的处理方式,可能会出现什么问题
epoll_wait&EINTR? socket read/write/close 有什么问题会导致上述问题吗?或者使用 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 并试图让 epoll_wait() 返回 errno。它是 4 (EINTR)
如果您至少向我们展示 strace
输出的片段,那将会更有帮助。至少,它会告诉我们正在接收到哪个中断。
没有这些信息,我无法告诉您您的程序有什么问题。不过,我可以告诉你如何找出答案。
首先,查看strace 输出。它会告诉你进程接收到的是什么信号。
然后查看该信号的信号处理程序。如果您没有,请注册一个。请确保您使用的是 sigaction
而不是 signal
。另外,请确保您使用的是较新的 sa_sigaction
函数格式。
使用这种格式,您的信号处理程序会收到有关谁发送该信号的信息。这包括发送者的 PID,如果它是定时器,则定时器 ID 等。使用该信息来确定信号的来源。
我有一个线程负责轮询各种fds。我正在使用 epoll_wait 并设置了超时。 以下是代码片段:
do {
n = epoll_wait(epollFd, eventsList, eventsTotal, timeoutMS);
}
while ((n<0) && (errno == EINTR));
eventsList内存包含timerfd、signalfd和socket fd。
该线程运行良好并处理定时器事件、套接字open/read/write/close 事件和用户定义的信号事件。
但有时线程会进入无限 do-while 循环,因为 errno 总是 returns EINTR.
Top -H 线程显示状态为睡眠。 strace 显示它正在调用
epoll_wait() 循环。
所以我使用的是广为接受的处理方式,可能会出现什么问题 epoll_wait&EINTR? socket read/write/close 有什么问题会导致上述问题吗?或者使用 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 并试图让 epoll_wait() 返回 errno。它是 4 (EINTR)
如果您至少向我们展示 strace
输出的片段,那将会更有帮助。至少,它会告诉我们正在接收到哪个中断。
没有这些信息,我无法告诉您您的程序有什么问题。不过,我可以告诉你如何找出答案。
首先,查看strace 输出。它会告诉你进程接收到的是什么信号。
然后查看该信号的信号处理程序。如果您没有,请注册一个。请确保您使用的是 sigaction
而不是 signal
。另外,请确保您使用的是较新的 sa_sigaction
函数格式。
使用这种格式,您的信号处理程序会收到有关谁发送该信号的信息。这包括发送者的 PID,如果它是定时器,则定时器 ID 等。使用该信息来确定信号的来源。