我试图了解信号处理的工作原理,所以我决定用另一种方式处理除以零。程序应请求输入,直到不被零除为止。但是,我的处理程序在第一次跳转后被忽略,除法由系统处理。为什么会这样?
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
jmp_buf env;
void handler(int sig) {
printf("Invalid input , try again\n");
longjmp(env , 1);
}
int main() {
signal(SIGFPE , handler);
int x , y;
setjmp(env);
scanf("%d%d" , &x , &y);
printf("%d\n" , x / y);
}
最佳答案
您需要使用 sigsetjmp
和 siglongjmp
而不是常规版本,因为常规版本无法正确恢复您的信号掩码。这是您的代码的工作版本:
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
jmp_buf env;
void handler(int sig) {
printf("Invalid input , try again\n");
siglongjmp(env , 1);
}
int main() {
int x , y;
signal(SIGFPE , handler);
sigsetjmp(env, 1);
scanf("%d%d" , &x , &y);
printf("%d %d\n" , x, y);
printf("%d\n" , x / y);
}
顺便说一下,我尝试按照 Joachim Pileborg 在评论中的建议使用 sigaction
,但它对我没有帮助。我认为这里的关键是,如果您只是简单地使用 longjmp
退出信号处理程序,则不会恢复信号上下文(这意味着 SIGFPE 可能处于禁用状态)。
关于c - Linux 中的信号处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27216682/