进程的信号掩码【sigprocmask(int what,const sigset_t *set,sigset_t *oldset)】

例如有SIGHUP的信号处理程序,someString是指向字符串的全局变量:

void handleHup(int signum)
{
	free(someString);
	someString=strdup("a different string.");
}


假设程序正在复制一个字符串的时候:

src=someString;
while(*src) *dest++=*src++;

一个SIGHUP信号到达,src将指向被释放的内存。

 

所以我们希望让一段代码不受信号的打扰,这要用到信号掩码(就是说明哪些信号可以不予响应,也叫阻塞)。

由函数:

int sigprocmask(int what,const sigset_t *set,sigset_t *oldset);
信号掩码这里都看不到他的影子,没用特定的东西保存他,总之,有两个东西,一是set,二是信号掩码,他们都是sigset_t类型。
当这样调用函数sigprocmask(0,NULL,&oldset);时,当前的信号掩码会复制一份到oldset。

what:1)SIG_BLOCK:把set中的信号加到当前信号掩码中。
  2)SIG_UNBLOCK:把set中的信号从当前信号掩码中除掉。
  3)SIG_SETMASK:把set的信号付给信号掩码。

example:

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

void checkmask(sigset_t* sigset=NULL);//print sigset的信号集,默认print 信号掩码

int main()
{
	char buffer[100];
	sigset_t blockset,sigset;
  
	sigemptyset(&blockset);
	sigaddset(&blockset,SIGINT);//blockset=SIGINT、SIGTSTP
	sigaddset(&blockset,SIGTSTP);
  
	sigprocmask(SIG_SETMASK,&blockset,&sigset);//信号掩码=blockset,sigset保存的是上次的信号掩码
 
	puts("first before sigprocmask,the mask:");
	checkmask(&sigset);
  
	puts("first after sigprocmask, the mask: ");
	checkmask();  
  
	printf("-------------------\n");

	sigaddset(&blockset,SIGTERM);
	sigprocmask(SIG_BLOCK,&blockset,&sigset);//信号掩码|=blockset
  
	puts("second before sigprocmask,the mask:");
	checkmask(&sigset);
  
	puts("second after sigprocmask, the mask: ");
	checkmask();

	printf("-------------------\n");
  
	sigdelset(&blockset,SIGINT);
	sigdelset(&blockset,SIGTERM);
	sigprocmask(SIG_UNBLOCK,&blockset,&sigset);//信号掩码-=blockset
  
	puts("third before sigprocmask,the mask:");
	checkmask(&sigset);
  
	puts("third after sigprocmask, the mask: ");
	checkmask();

	printf("---------------\nfinish!!\n");

	return 0;
}

void checkmask(sigset_t *s)
{
	sigset_t sigset;
	if(s==NULL) 
	{
		if(sigprocmask(0,NULL,&sigset)<0)//get 信号掩码
		{
			printf("Sigprocmask error");
			return ;
		}
	}
	else sigset=(*s);
  
	if(sigismember(&sigset,SIGINT))
	printf("SIGINT\n");
  
	if(sigismember(&sigset,SIGTSTP))
	printf("SIGTSTP\n");

	if(sigismember(&sigset,SIGTERM))
	printf("SIGTERM\n");
}
//output:
/*
first before sigprocmask,the mask:
first after sigprocmask, the mask: 
SIGINT
SIGTSTP
-------------------
second before sigprocmask,the mask:
SIGINT
SIGTSTP
second after sigprocmask, the mask: 
SIGINT
SIGTSTP
SIGTERM
-------------------
third before sigprocmask,the mask:
SIGINT
SIGTSTP
SIGTERM
third after sigprocmask, the mask: 
SIGINT
SIGTERM
---------------
finish!!
*/


 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
sigset_t 是一个用于存储信号集合的数据类型,它是一个位图,每个位代表一个信号。在使用 sigset_t 之前,需要先使用 sigemptyset 函数将其初始化为空集。 sigset_t 可以用于设置线程或进程信号掩码,即哪些信号会被阻塞或接收。可以使用 sigaddsetsigdelset 函数向信号集合中添加或删除信号sigismember 函数用于判断信号是否在信号集合中。 下面是一个简单的例子,演示了 sigset_t 的基本用法: ```c #include <stdio.h> #include <stdlib.h> #include <signal.h> int main() { sigset_t set; // 初始化为空集 sigemptyset(&set); // 添加 SIGINTSIGTERM 信号 sigaddset(&set, SIGINT); sigaddset(&set, SIGTERM); // 判断 SIGINTSIGKILL 是否在信号集合中 if (sigismember(&set, SIGINT)) { printf("SIGINT is in the signal set\n"); } if (sigismember(&set, SIGKILL)) { printf("SIGKILL is in the signal set\n"); } // 删除 SIGTERM 信号 sigdelset(&set, SIGTERM); // 判断 SIGTERM 是否在信号集合中 if (sigismember(&set, SIGTERM)) { printf("SIGTERM is in the signal set\n"); } else { printf("SIGTERM is not in the signal set\n"); } return 0; } ``` 在上面的例子中,我们首先使用 sigemptyset 函数将 sigset_t 初始化为空集。然后使用 sigaddset 函数向信号集合中添加 SIGINTSIGTERM 信号,使用 sigismember 函数判断 SIGINTSIGKILL 是否在信号集合中。接着使用 sigdelset 函数将 SIGTERM 信号信号集合中删除,最后再次使用 sigismember 函数判断 SIGTERM 是否在信号集合中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值