【Linux】阻塞信号

LInux中信号产生的原因大致有一下三种:

  1. 键盘中断
  2. 命令发出
  3. 异常产生中断

但归根结底,这些信号其实都是最终有操作系统发出的。

常见的对信号的处理,无外乎以下三种:

  1. 忽略
  2. 终止该进程
  3. 自定义行为

对信号的处理动作叫做信号递达,在信号由产生到递达的过程中还有一种状态叫做未决。即信号虽产生,但是未被处理。这个时候就需要将信号保存起来。

信号的种类:

         

其中,前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:

                   

知道解除阻塞,这个信号才会在恰当的时候被处理。

阅读更多
版权声明:本文为博主原创文章,转载需注明出处。 https://blog.csdn.net/qq_33724710/article/details/51867795
文章标签: linux 信号
个人分类: C语言 Linux
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭