这里有我的代码,我无法使用信号中断主循环。当我启动SIGUSR1时,会调用信号处理程序,但我不会取消阻止pselect。
#include <errno.h>
#include <signal.h>
#include <stdio.h>
int end = 1;
void handler(int sig) {
end = 1;
}
int main() {
sigset_t blockset;
struct sigaction sa;
int res;
/* Block the signal */
sigemptyset(&blockset);
sigaddset(&blockset, SIGUSR1);
sigprocmask(SIG_BLOCK, &blockset, NULL);
/* Install handler */
sa.sa_sigaction = handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
sigaction(SIGUSR1, &sa, NULL);
/* Unblock signal; wait for signal */
while(end) {
sigemptyset(&emptyset); /* Signal mask to use during pselect() */
res = pselect(0, NULL, NULL, NULL, NULL, &emptyset);
if (errno == EINTR)
printf("Interrupted by SIGUSR1.");
}
}
答案 0 :(得分:3)
起初,我认为这是因为您使用的是SA_RESTART
。这与你想要的相反。但是,事实证明pselect
忽略了SA_RESTART
,所以不是这样。
事实证明,pselect
正在返回,而errno
是 EINTR
。您根本没有看到该消息,因为您没有刷新stdout
的缓冲区!
您可以在将输出发送到fflush
后使用stdout
来执行此操作。
fflush(stdout);
但是stdout
在输出到终端时是行缓冲的,所以简单地添加缺少的换行就可以了。
printf("Interrupted by SIGUSR1.\n");
如果没有第二个错误,你甚至都不会注意到上述问题。 stdout
通常在程序退出时刷新,但由于你有
int end = 1;
void handler(int sig) {
end = 1;
}
while (end) { ... }
当你想要做的时候
int end = 0;
void handler(int sig) {
end = 1;
}
while (!end) { ... }