我想了解信号处理的工作原理,因此我决定以另一种方式处理除以零。程序应请求输入,直到不发生被零除为止。但是,我的处理程序在第一次跳转后被忽略,并且除法由系统处理。为什么会出现这种情况?
#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);
}
Run Code Online (Sandbox Code Playgroud)
您需要使用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);
}
Run Code Online (Sandbox Code Playgroud)
顺便说一句,我尝试sigaction按照 Joachim Pileborg 在评论中的建议使用,但这对我没有帮助。我认为这里的关键是,如果您只是简单地longjmp退出信号处理程序,则信号上下文不会恢复(意味着 SIGFPE 可能会处于禁用状态)。