LInux中信号产生的原因大致有一下三种:
- 键盘中断
- 命令发出
- 异常产生中断
但归根结底,这些信号其实都是最终有操作系统发出的。
常见的对信号的处理,无外乎以下三种:
- 忽略
- 终止该进程
- 自定义行为
对信号的处理动作叫做信号递达,在信号由产生到递达的过程中还有一种状态叫做未决。即信号虽产生,但是未被处理。这个时候就需要将信号保存起来。
信号的种类:
其中,前31个信号属于普通信号,后31个属于实时信号,这里不讨论实时信号。
普通信号有31个,足以用一个4字节的变量来保存。于是就有了block(阻塞)表和pending(未决)表。
其中task_struct,就是LInux中的PCB的名称。在PCB中维护了三张表,分别是block,pending, handler表,block表示哪一个信号被阻塞,它的下标的值加1代表对应被阻塞的信号。pending表表示哪个信号处于未决状态,表示方法同block,横向看过去handler,分别代表捕获到该信号时的处理方式。
下面利用一小段程序来测试打印一下pending表:
#include <stdio.h> #include <signal.h> #include <unistd.h> void printsigset(sigset_t *set) { int i = 0; for (; i < 32; ++i) { if (sigismember(set, i)) //查看信号i对应的位是否为被置1 { putchar('1'); } else { putchar('0'); } } puts(""); } int main() { sigset_t s, p; sigemptyset(&s); //初始化:0 sigemptyset(&p); sigaddset(&s, SIGINT); sigprocmask(SIG_BLOCK, &s, NULL); while (1) { sigpending(&p); printsigset(&p); sleep(1); } return 0; }
初始时输出如下:
现在有一个信号1处于未决状态,当按下键盘上的CtrlC时,将会产生一个2信号给该进程,对应的位会被置1:
知道解除阻塞,这个信号才会在恰当的时候被处理。
【Linux】阻塞信号
最新推荐文章于 2024-08-09 23:30:21 发布