考虑以下程序:
#include <stdio.h>
#include <sys/epoll.h>
int main(void) {
int epfd = epoll_create1(0);
struct epoll_event event;
event.events = EPOLLIN;
event.data.fd = 0;
epoll_ctl(epfd, EPOLL_CTL_ADD, 0, &event);
epoll_wait(epfd, &event, 1, -1);
perror("epoll_wait");
return 0;
}
当我自己运行该程序时,调整终端的大小(从而生成SIGWINCH)不会对其执行任何操作,并且会一直等待stdin上的输入。当我在strace或ltrace中运行它时,SIGWINCH导致epoll_wait出现EINTR错误。我对EINTR的理解是,仅当信号在您的代码中调用信号处理程序时才生成它,但是我没有注册它们中的任何一个。我以为strace或ltrace可能已经为我设置了一个,所以我尝试将其显式设置为SIG_IGN,但这仍然没有停止EINTR。为什么会这样呢?
他们使用ptrace(2)
,其手册页注释
在跟踪过程中,即使信号被忽略,每次发送信号时,跟踪都会停止。(一个例外是
SIGKILL
,它具有通常的效果。)跟踪程序将在其下一次调用waitpid(2)
(或相关的“等待”系统调用之一)时得到通知;该调用将返回一个状态值,该状态值包含指示示踪停止的原因的信息。停止跟踪时,跟踪器可以使用各种ptrace请求来检查和修改跟踪。然后,跟踪程序使跟踪程序继续进行,可以选择忽略所传递的信号(或什至替代地传递不同的信号)。
然后:
请注意,被抑制的信号仍然会导致系统调用过早返回。在这种情况下,系统调用将重新启动:如果跟踪器使用,则跟踪器将观察被跟踪者以重新执行被中断的系统调用(或
restart_syscall(2)
使用不同的重新启动机制的一些系统调用的系统调用)PTRACE_SYSCALL
。甚至poll(2)
在信号被抑制后重新启动的系统调用(例如)也无法重新启动;但是,存在内核错误,即使没有将可观察到的信号注入到tracee中,也会导致某些系统调用因EINTR失败。
默认情况下,SIGWINCH
被忽略,但它听起来好像epoll
是类似够poll
了EINTR
是给调用者(甚至与重启)可见。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句