简单举例sigpromask
#include<stdio.h>
#include<signal.h>
#include<unistd.h>
#include<string.h>
void handler(int sig);
void printsigset(sigset_t *set)
{
int i;
for(i=1;i<NSIG;++i)//NSIG是LINUX规定信号量总数
{
if(sigismember(set,i))//判断某一信号是否在给定集合中
putchar('1');
else
putchar('0');
}
printf("\n");
}
int main(int argc,char *argv[])
{
sigset_t pset;
sigset_t bset;
//类似于memset一样的初始化工作
sigemptyset(&bset);
sigaddset(&bset,SIGINT);
if(signal(SIGINT,handler)==SIG_ERR)
perror("signal error");
if(signal(SIGQUIT,handler)==SIG_ERR)
perror("signal error");
//将SIGINT置为阻塞状态
sigprocmask(SIG_BLOCK,&bset,NULL);
for(;;)
{
//返回当前所有被挂起的信号
sigpending(&pset);
printsigset(&pset);
sleep(1);
}
return 0;
}
void handler(int sig)
{
if(sig==SIGINT)
printf("recv a sig = %d\n",sig);
else if(sig==SIGQUIT)
{
sigset_t uset;
sigemptyset(&uset);
sigaddset(&uset,SIGINT);
//将SIGINT信号置成非阻塞状态
sigprocmask(SIG_UNBLOCK,&uset,NULL);
}
}
执行结果:
[root@izwz9j36enzsqqima735r4z cprograms]# ./sigset01
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
//按ctrl+c
^C0100000000000000000000000000000000000000000000000000000000000000
0100000000000000000000000000000000000000000000000000000000000000
0100000000000000000000000000000000000000000000000000000000000000
0100000000000000000000000000000000000000000000000000000000000000
0100000000000000000000000000000000000000000000000000000000000000
//在另一个终端 ps aux
//执行 #kill -QUIT 11651
//当前终端
recv a sig = 2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
//再按ctrl+c
^C0100000000000000000000000000000000000000000000000000000000000000
0100000000000000000000000000000000000000000000000000000000000000
//使进程终止
^Z
[1]+ 已停止 ./sigset01
- 一定要注意的是,一开始输出显示2号信号并不是pending状态,
因为即使一开始设置为了block,但由于还没有发送信号,因此并没有任何一个信号处于pending状态
sigaction以及不可靠信号举例
#include<stdio.h>
#include<signal.h>
#include<unistd.h>
#include<string.h>
void handler(int sig);
int main(void)
{
struct sigaction act;
act.sa_handler=handler;
sigemptyset(&act.sa_mask);
act.sa_flags=0;
if(sigaction(SIGINT,&act,NULL)<0)
{
perror("error");
}
for(;;)
//使进程处于挂起状态,这样能尽可能小的占用cpu资源,又能接受信号
pause();
return 0;
}
void handler(int sig)
{
printf("recv a sig=%d\n",sig);
int n=30;
do
{
/*注意,这儿一定得这样写,因为进程被唤醒时,sleep会直接返 回,返回值就是还剩下的睡眠时间*/
n=sleep(n);
}while(n>0);
}
测试结果:
先运行
#./sigaction
//按ctrl+c,处理函数输出
^Crecv a sig=2
//处理函数处于睡眠状态,此时再按ctrl+c没反应
//不可靠信号就体现在这儿,此时无论发送了多少了信号,都只会保留一个
//因此能看到的结果是,30s过后,只打印输出一次,
//再等下一个30s到来,也没有第二次的打印输出了
^C^C^C^Crecv a sig=2
^Z
[1]+ 已停止 ./sigaction