白银做网站,视频制作软件下载安装,装潢设计图片三室一厅,做代练的网站摘要#xff1a; 在信号处理函数执行时#xff0c;会阻塞当前信号。当信号处理函数返回时#xff0c;系统会帮我们把刚刚阻塞的信号再从阻塞集中移除。一、 临时阻塞特性
当执行信号处理函数的时候#xff0c;会临时将当前被处理信号阻塞。为了能说明问题#xff0c;采用…摘要 在信号处理函数执行时会阻塞当前信号。当信号处理函数返回时系统会帮我们把刚刚阻塞的信号再从阻塞集中移除。一、 临时阻塞特性
当执行信号处理函数的时候会临时将当前被处理信号阻塞。为了能说明问题采用实验来验证。
下面这段程序在收到 SIGALRM 信号或者 SIGQUIT 信号时会打印当前信号同时打印当前被阻塞的信号。
测试代码
#include unistd.h
#include signal.h
#include setjmp.h
#include stdio.hvoid printBlock() {sigset_t block;sigprocmask(SIG_BLOCK, NULL, block);printf(block:);if (sigismember(block, SIGQUIT)) printf(SIGQUIT, );if (sigismember(block, SIGALRM)) printf(SIGALRM\t);puts();
}void handler(int sig) {if (sig SIGQUIT) printf(SIGQUIT, );if (sig SIGALRM) printf(SIGALRM, );printBlock();puts(--------------------------------------------------);
}int main() {printf(Im %d\n, getpid());signal(SIGQUIT, handler);signal(SIGALRM, handler);printf(before signal, );printBlock();while (1) {pause();}return 0;
}
输出结果 结果分析
可以看到当程序收到 SIGALRM 信号时在信号处理函数中 SIGALRM 信号会被临时阻塞SIGQUIT 信号同理。
执行完毕再从阻塞信号集中移除我就不验证了。实际上你重复发送 SIGALRM 信号信号处理函数都能正常执行就已经证明 SIGALRM 信号未被阻塞当然了如果你手速比 cpu 运行的还快可能会有信号合并的情况这种不在考虑之列。 二、跳出你的信号处理函数
试想一下如果你在信号处理函数中使用 longjmp 跳走了系统会不会帮你把临时阻塞的信号给撤走答案是不会。这将导致程序 bug。从此以后你的程序再也不能处理该信号了。空口无凭用实验说话。
下面这段程序在信号处理函数中打印当前信号和当前被阻塞的信号。完成后没有直接 return而是使用 longjmp 跳转到 setjmp 的位置。接下来再打印阻塞信号。
测试代码
#include unistd.h
#include signal.h
#include setjmp.h
#include stdio.hjmp_buf jmpbuf;void printBlock()
{sigset_t block;sigprocmask(SIG_BLOCK, NULL, block);printf(block:);if (sigismember(block, SIGQUIT)) printf(SIGQUIT, );if (sigismember(block, SIGALRM)) printf(SIGALRM);puts();
}void handler(int sig)
{if (sig SIGQUIT) printf(SIGQUIT, );if (sig SIGALRM) printf(SIGALRM, );printBlock();longjmp(jmpbuf, 1);puts(--------------------------------------------------);
}int main()
{printf(Im %d\n, getpid());signal(SIGQUIT, handler);signal(SIGALRM, handler);printf(before signal, );printBlock();if (setjmp(jmpbuf) ! 0) {printf(jump to here! );printBlock();puts();}while (1) {pause();}return 0;
} 输出结果 结果分析
可以看到当 jump 到 main 函数中的时候SIGQUIT 依然被阻塞了SIGALRM 也是。此后无论你再怎么发送这两个信号处理函数也不会执行了。因为这两个信号没有从阻塞集中删除。
这是 bug。
解决方案是使用另外两个函数分别是 sigsetjmp 和 siglongjmp。所以我们只要把上面代码中的 setjmp 和 longjmp 分别替换成这两个函数就行了。 三、函数sigsetjump和siglongjump应用
1. 测试代码
#include unistd.h
#include signal.h
#include setjmp.h
#include stdio.hjmp_buf jmpbuf;void printBlock() {sigset_t block;sigprocmask(SIG_BLOCK, NULL, block);printf(block:);if (sigismember(block, SIGQUIT)) printf(SIGQUIT, );if (sigismember(block, SIGALRM)) printf(SIGALRM);puts();
}void handler(int sig) {if (sig SIGQUIT) printf(SIGQUIT, );if (sig SIGALRM) printf(SIGALRM, );printBlock();siglongjmp(jmpbuf, 1); puts(--------------------------------------------------);
}int main() {printf(Im %d\n, getpid());signal(SIGQUIT, handler);signal(SIGALRM, handler);printf(before signal, );printBlock();if (sigsetjmp(jmpbuf, 1) ! 0) {printf(jump to here! );printBlock();puts();}while(1) {pause();}return 0;
}
输出结果 四、参考资料
1. 47-跳出信号处理函数