赞
踩
实际执行信号的处理动作称为信号递达(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); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。