【Linux】信号的阻塞

  • 信号阻塞

概念

  • 信号递达:执行信号的处理过程叫做信号递达(Delivery)。
  • 信号未决:信号从产生到递达之间的状态成为信号未决(Pending)。
  • 信号阻塞:进程可以选择阻塞(Block)某个信号。

 需要注意的是:

  • 被阻塞的信号产生时将保持在未决状态,直到进程解除对该信号的阻塞,才执行递达的动作。
  • 阻塞和忽略是不一样的,阻塞是信号还未被处理,而忽略是信号处理的一种方式。
  • 所有的信号如果都未被阻塞,那么所有信号将被递达;所有的信号如果都被block,那么一定不会被递达。

在操作系统中的表示:

信号在操作系统底层的表示,如下图:

信号阻塞的相关函数:

sigprocmask

int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

作用:读取进程的信号屏蔽字(阻塞信号集)

how:如何更改信号集中的信号,有三个选项

  • SIG_BLOCK:设置当前信号屏蔽字的信号
  • SIG_UNBLOCK:解除当前信号屏蔽字中阻塞的信号
  • SIG_SETMASK:把当前信号屏蔽字设置为什么样子

set:把哪些信号进行设置

oset:把老的block表保存到oldset

返回值:若成功,返回0,失败返回-1

sigpending

 int sigpending(sigset_t *set);
  • 作用:读取当前进程的信号未决集,通过set参数传出
  • set:把哪些信号进行设置
  • 返回值:若成功,返回0,失败返回-1

实例代码:

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

void handler(int signo)
{
	printf("AAAAAAA\n", signo);
}

void show(sigset_t *pending)//显示pending表
{
	int i = 0;
	for (i = 0; i <= 31; i++)
	{
		if (sigismember(pending, i))//判断i是否在信号集中,如果是,证明该信号已被pending
		{
			printf("1");
		}
		else
		{
			printf("0");
		}
	}
	printf("\n");
}

int main()
{
	sigset_t set, oset;
	sigemptyset(&set);//初始化set
	sigemptyset(&oset);//初始化oset
	sigaddset(&set, 2);//把2号信号添加到信号集中
	sigprocmask(SIG_SETMASK, &set, &oset);//读取信号集中的信号
	signal(2, handler);//捕捉2号信号
	sigset_t pending;//定义pending表
	int i = 10;
	while (1)//不断获取pending表
	{
		sigpending(&pending);//获得当前进程的pending信号集
		show(&pending);//显示pending表
		sleep(1);
		if ((i--) == 0)//每隔一秒显示一次pending表
		{
			sigprocmask(SIG_SETMASK, &oset, NULL);//把2号信号从阻塞信号集中去掉
		}
	}

	return 0;
}

执行结果:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值