这是我的代码,我无法使用信号中断主循环。当我启动时,会调用 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.");
}
}
一开始我以为是因为你使用了
SA_RESTART
。这与你想要的相反。然而,事实证明pselect
忽略了SA_RESTART
,所以不是这样的。
事实证明,
pselect
is回归,errno
isEINTR
。您只是没有看到该消息,因为您没有刷新 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) { ... }