如果在处理过程中收到另一个信号,信号处理程序将如何工作?
How exactly signal handler will work if it receives another signal while processed?
我试图测试信号处理程序中到底发生了什么。
int num = 0;
void handler(int signum, siginfo_t *sip, void *ptr)
{
sleep(1);
num ++;
write(1, "processs!\n", 10);
}
int main(void)
{
int pid = getpid();
struct sigaction act1;
printf("%d\n", pid);
//act1.sa_flags = SA_NODEFER;
act1.sa_sigaction = &handler;
sigaction(SIGUSR1, &act1, NULL);
sigaction(SIGUSR2, &act1, NULL);
while (1)
{
sleep(1);
printf("%d\n", num);
};
}
在其他过程中,我发送了两个信号,如下所示:
杀死(pid,SIGUSR1);
杀死(pid,SIGUSR1);
据我所知,信号处理程序会阻塞调用其自身的信号..... 并在处理程序结束后处理阻塞的信号。我希望处理程序将被调用两次并且全局变量 num 将为 2;
但只调用了一次,num 为 1。
然后我尝试像这样发送两个不同的信号:
杀死(pid,SIGUSR1);
杀死(pid,SIGUSR2);
据我所知,SIGUSR2 将在处理程序仍在睡眠期间处理,并且第一个处理程序将在此处退出,并且 num ++ 将不起作用。它只会在稍后调用的处理程序中处理一次。
但是处理程序被调用了两次,在这次试验中 num 是 2....
我对信号处理程序的想法有什么误解吗?我很困惑。
这是你的误解:
and this first handler will quit here, and num ++ will not work.
当一个信号处理程序中断另一个信号处理程序时,一旦中断信号处理程序完成,被中断的信号处理程序就会从中断处恢复。它不只是提前结束。
顺便说一句,你的代码有很多问题:
- 由于您没有使用
SA_SIGINFO
,因此您的 handler
应该只接受一个参数并且应该进入 sa_handler
而不是 sa_sigaction
。
- 您没有初始化
struct sigaction
的大部分字段,因此当您对其调用 sigaction
时,可能会发生非常奇怪的事情。
- 您在信号处理程序中可以执行的操作确实受到限制;特别是,您不能访问
int
类型的全局变量。将 num
更改为 volatile sig_atomic_t
.
- 你基本上不应该在循环之外使用
write
,因为部分写入基本上可以在任何时候发生。
至于为什么发送 SIGUSR1
两次并不总是 运行 处理程序两次,那是因为 non-real-time 信号允许合并,所以如果你的第二个 kill
发生在第一个的信号处理程序开始 运行ning 之前,那么第二个实际上不会做任何事情。
我试图测试信号处理程序中到底发生了什么。
int num = 0;
void handler(int signum, siginfo_t *sip, void *ptr)
{
sleep(1);
num ++;
write(1, "processs!\n", 10);
}
int main(void)
{
int pid = getpid();
struct sigaction act1;
printf("%d\n", pid);
//act1.sa_flags = SA_NODEFER;
act1.sa_sigaction = &handler;
sigaction(SIGUSR1, &act1, NULL);
sigaction(SIGUSR2, &act1, NULL);
while (1)
{
sleep(1);
printf("%d\n", num);
};
}
在其他过程中,我发送了两个信号,如下所示: 杀死(pid,SIGUSR1); 杀死(pid,SIGUSR1);
据我所知,信号处理程序会阻塞调用其自身的信号..... 并在处理程序结束后处理阻塞的信号。我希望处理程序将被调用两次并且全局变量 num 将为 2;
但只调用了一次,num 为 1。
然后我尝试像这样发送两个不同的信号: 杀死(pid,SIGUSR1); 杀死(pid,SIGUSR2);
据我所知,SIGUSR2 将在处理程序仍在睡眠期间处理,并且第一个处理程序将在此处退出,并且 num ++ 将不起作用。它只会在稍后调用的处理程序中处理一次。
但是处理程序被调用了两次,在这次试验中 num 是 2....
我对信号处理程序的想法有什么误解吗?我很困惑。
这是你的误解:
and this first handler will quit here, and num ++ will not work.
当一个信号处理程序中断另一个信号处理程序时,一旦中断信号处理程序完成,被中断的信号处理程序就会从中断处恢复。它不只是提前结束。
顺便说一句,你的代码有很多问题:
- 由于您没有使用
SA_SIGINFO
,因此您的handler
应该只接受一个参数并且应该进入sa_handler
而不是sa_sigaction
。 - 您没有初始化
struct sigaction
的大部分字段,因此当您对其调用sigaction
时,可能会发生非常奇怪的事情。 - 您在信号处理程序中可以执行的操作确实受到限制;特别是,您不能访问
int
类型的全局变量。将num
更改为volatile sig_atomic_t
. - 你基本上不应该在循环之外使用
write
,因为部分写入基本上可以在任何时候发生。
至于为什么发送 SIGUSR1
两次并不总是 运行 处理程序两次,那是因为 non-real-time 信号允许合并,所以如果你的第二个 kill
发生在第一个的信号处理程序开始 运行ning 之前,那么第二个实际上不会做任何事情。