[英]why signal() function in C only works once
这是我的代码:
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<setjmp.h>
void sighandler(int signum);
jmp_buf buf;
void main(){
signal(SIGINT,sighandler);
if(!setjmp(buf))
printf("welcome to this game\n");
int a = 1;
printf("raw value of a is %d\n",a);
printf("modify a:");
scanf("%d",&a);
printf("new value of a is %d\n",a);
}
void sighandler(int signum){
if(signum == SIGINT){
printf("\nyou can't quit this game by ctrl+C,now we will restart it\n");
longjmp(buf,1);
}
}
我在 ubuntu 上运行它,结果如下:
welcome to this game
raw value of a is 1
input num to modify a:^C
you can't quit this game by ctrl+C,now we will restrat it
raw value of a is 1
input num to modify a:^C
似乎 signal() 仅第一次捕获 SIGINT。 我在网站上阅读了一些答案,例如:
“当一个信号被传递时,它在处理程序的执行过程中也会被阻塞(如果从 SIGINT 传递中调用它,则在 sigint_handler 中执行时不会传递任何 SIGINT);”
但我不明白,因为我的 signal_handler function 应该很快退出。 我不知道为什么被阻止。有没有办法让它第二次或第三次工作? 谢谢
在您的信号处理程序中,SIGINT 被阻止,也就是说,它被添加到您的进程的信号掩码中。 (1)
当您使用longjmp
(非本地 goto)离开信号处理程序时,信号掩码不会被触及。 因此,当您在setjmp
点恢复执行时,您会保留处理程序设置的信号掩码。 (2)
sigsetjmp
和siglongjmp
通过保存和恢复信号掩码解决了这个问题。
但是,我建议您重新编写代码以完全避免非本地 goto。 它们可以安全使用,但容易误用且难以推理。
笔记:
signal
的这种行为很常见,但并不普遍,这是更喜欢sigaction
signal
而不是 signal 的一个很好的理由。您实际上并没有从信号处理程序返回(当然,您退出它,但您没有从它返回 - 您只是跳转到另一个上下文)。 如果您让信号处理程序返回,您的代码将在它停止的地方继续执行,并且它会按照您想要的方式拦截任何后续的 SIGINT 信号。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.