文章目录
- 八、进程信号
- 2. 信号的保存
- 3. 信号的处理
- 未完待续
八、进程信号
2. 信号的保存
实际执行信号的处理动作称为信号递达(Delivery)
信号从产生到递达之间的状态,称为信号未决(Pending)。
进程可以选择阻塞 (Block )某个信号。
被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作。
注意,阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作。
在进程的PCB中,有两个位图,一个是判断是否收到相应信号的位图pending,一个是决定该位置的信号是否阻塞的位图block。
handler表是一组函数指针,决定信号的执行方法。
调用函数 sigprocmask 可以读取或更改进程的信号屏蔽字(阻塞信号集)。
int main()
{
// 创建阻塞信号集
sigset_t block, oblock;
// 清空信号集
sigemptyset(&block);
sigemptyset(&oblock);
// 将2号信号添加进阻塞信号集
sigaddset(&block, 2);
// 将阻塞信号集设置到内核中
int n = sigprocmask(SIG_SETMASK, &block, &oblock);
assert(n == 0);
while (true)
{
// 创建pending信号集
sigset_t pending;
sigemptyset(&pending);
// 获取pending信号集
n = sigpending(&pending);
assert(n == 0);
// 打印pending信号集
PrintSig(pending);
sleep(1);
}
return 0;
}
9号信号、19号信号无法被屏蔽,18号信号会做特殊处理。操作系统不允许出现 金刚不坏 的进程。
如何解除屏蔽?
while (true)
{
int cnt = 0;
// 创建pending信号集
sigset_t pending;
sigemptyset(&pending);
// 获取pending信号集
n = sigpending(&pending);
assert(n == 0);
// 打印pending信号集
PrintSig(pending);
++cnt;
if (cnt == 20)
{
// 解除阻塞信号集
n = sigprocmask(SIG_UNBLOCK, &block, &oblock);
assert(n == 0);
}
sleep(1);
}