【问题标题】:epoll_wait() returns EINTR infinitelyepoll_wait() 无限返回 EINTR
【发布时间】:2017-09-30 11:03:41
【问题描述】:

我有一个线程负责轮询各种 fd。我正在使用设置了超时的 epoll_wait。 以下是代码sn-p:

do {
    n = epoll_wait(epollFd, eventsList, eventsTotal, timeoutMS);
} 
while ((n<0) && (errno == EINTR));

eventsList 内存包含 timerfd、signalfd 和 socket fd。

线程运行良好并处理定时器事件、套接字打开/读取/写入/关闭事件和用户定义的信号事件。

但有时线程会进入无限 do-while 循环,因为 errno 总是返回 EINTR
Top -H 的线程显示状态为睡眠。 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并试图让epoll_wait()返回errno。它是 4 (EINTR)

【问题讨论】:

  • EINTR 通常意味着信号中断了epoll 系统调用。尝试找出正在发送的信号,然后您可以找出原因以及如何解决问题。
  • 你能把 strace 的输出贴在你看到这种行为的地方吗?

标签: linux multithreading sockets epoll eintr


【解决方案1】:

如果您至少向我们展示了strace 输出的一个sn-p,那将会更有帮助。至少,它会告诉我们正在接收哪个中断。

没有这些信息,我无法告诉您您的程序出了什么问题。不过,我可以告诉你如何找出答案。

首先,查看 strace 输出。它会告诉你进程接收到的信号是什么。

然后查看该信号的信号处理程序。如果您没有,请注册一个。确保您使用的是 sigaction 而不是 signal 这样做。另外,请确保您使用的是较新的 sa_sigaction 函数格式。

使用这种格式,您的信号处理程序会接收有关谁发送了该信号的信息。这包括发送者的 PID,如果是定时器,定时器 ID 等。使用该信息来确定信号来自哪里。

【讨论】:

    猜你喜欢
    • 2011-10-15
    • 2012-08-04
    • 2017-12-20
    • 2013-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-20
    • 2022-01-12
    相关资源
    最近更新 更多