sigprocmask阻塞信号
2018-02-07 16:06
483 查看
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
参数的how:
SIG_BLOCK :附加set到阻塞表,原来的保存在到oldset
SIG_UNBLOCK:从阻塞表中删除set中的信号,原来的保存到oldset
SIG_SETMASK:清空阻塞表并设置为set,原来的保存到oldset
假设现在阻塞的信号表是{SIGSEGV,SIGSUSP},我们执行了以下代码:
sigset_t x,y;
sigemtyset(&x);
sigemtyset(&y);
sigaddset(&x,SIGUSR1);
sigprocmask(SIG_BLOCK,&x,&y);
则新的阻塞表是{SIGSEGV,SIGSUSP,SIGUSR1},y中保存的是{SIGSEGV,SIGSUSP}
如果我接着执行sigprocmask(SIG_UNBLOCK,&x,NULL),
则新的阻塞表是{SIGSEGV,SIGSUSP}
如果我接着执行sigprocmask(SIG_SETMASK,&x,NULL);
则新的阻塞表是{SIGUSR1}。
返回说明:
成 功执行时,返回0。失败返回 - 1 ,errno被设为EINVAL。
代码:
#include<stdio.h>
#include<signal.h>
#include<stdlib.h>
#include<sys/types.h>
void handler(int sig)
{
printf("get a sig,num is:%d\n",sig);
}
void print_sig(sigset_t *p)
{
int i = 1;
for(;i < 32;++i){
if(sigismember(p,i)){//信号集p中是否有信号i.
printf("1");
}else{
printf("0");
}
}
printf("\n");
}
int main()
{
signal(2,handler);//当接收到2(SIGINT,CTRL+C)信号,就执行handler函数
sigset_t s,p,o;//设置信号集
sigemptyset(&s);//清空信号集
sigemptyset(&o);
sigaddset(&s,SIGINT);//往信号集s中添加信号SIGINT
sigprocmask(SIG_SETMASK,&s,&o);
//SIG_SETMASK:清空阻塞表并设置为s,原来的保存到o中
int count = 0;
while(1){
sigemptyset(&p);
sigpending(&p);//获取当前进程信号发生位图,即获取当前进程中所有信号放入信号集p中.
print_sig(&p);
sleep(1);
if( count++ == 10 ){
sigprocmask(SIG_SETMASK,&o,NULL);
printf("recover block\n");
sleep(3);
}
}
}
代码2:
#include
#include
#include
#include
#include
int main(){
sigset_t initset;
int i;
sigemptyset(&initset);//初始化信号集合为空集合
sigaddset(&initset,SIGINT);//将SIGINT信号加入到此集合中去
while(1){
sigprocmask(SIG_BLOCK,&initset,NULL);//将信号集合加入到进程的阻塞集合中去
fprintf(stdout,"SIGINT singal blocked/n");
for(i=0;i<10;i++){
sleep(1);//每1秒输出
fprintf(stdout,"block %d/n",i);
}
//在这时按一下Ctrl+C不会终止
sigprocmask(SIG_UNBLOCK,&initset,NULL);//从进程的阻塞集合中去删除信号集合
fprintf(stdout,"SIGINT SINGAL unblokced/n");
for(i=0;i<10;i++){
sleep(1);
fprintf(stdout,"unblock %d/n",i);
}
}
exit(0);
}
执行结果:
SIGINT singal blocked
block 0
block 1
block 2
block 3
block 4
block 5
block 6
block 7
block 8
block 9
在执行到block 3时按下了CTRL+C并不会终止,直到执行到block9后将集合从阻塞集合中移除。
[root@localhost C]# ./s1
SIGINT singal blocked
block 0
block 1
block 2
block 3
block 4
block 5
block 6
block 7
block 8
block 9
SIGINT SINGAL unblokced
unblock 0
unblock 1
由于此时已经解除了阻塞,在unblock1后按下CTRL+C则立即终止。
参数的how:
SIG_BLOCK :附加set到阻塞表,原来的保存在到oldset
SIG_UNBLOCK:从阻塞表中删除set中的信号,原来的保存到oldset
SIG_SETMASK:清空阻塞表并设置为set,原来的保存到oldset
假设现在阻塞的信号表是{SIGSEGV,SIGSUSP},我们执行了以下代码:
sigset_t x,y;
sigemtyset(&x);
sigemtyset(&y);
sigaddset(&x,SIGUSR1);
sigprocmask(SIG_BLOCK,&x,&y);
则新的阻塞表是{SIGSEGV,SIGSUSP,SIGUSR1},y中保存的是{SIGSEGV,SIGSUSP}
如果我接着执行sigprocmask(SIG_UNBLOCK,&x,NULL),
则新的阻塞表是{SIGSEGV,SIGSUSP}
如果我接着执行sigprocmask(SIG_SETMASK,&x,NULL);
则新的阻塞表是{SIGUSR1}。
返回说明:
成 功执行时,返回0。失败返回 - 1 ,errno被设为EINVAL。
代码:
#include<stdio.h>
#include<signal.h>
#include<stdlib.h>
#include<sys/types.h>
void handler(int sig)
{
printf("get a sig,num is:%d\n",sig);
}
void print_sig(sigset_t *p)
{
int i = 1;
for(;i < 32;++i){
if(sigismember(p,i)){//信号集p中是否有信号i.
printf("1");
}else{
printf("0");
}
}
printf("\n");
}
int main()
{
signal(2,handler);//当接收到2(SIGINT,CTRL+C)信号,就执行handler函数
sigset_t s,p,o;//设置信号集
sigemptyset(&s);//清空信号集
sigemptyset(&o);
sigaddset(&s,SIGINT);//往信号集s中添加信号SIGINT
sigprocmask(SIG_SETMASK,&s,&o);
//SIG_SETMASK:清空阻塞表并设置为s,原来的保存到o中
int count = 0;
while(1){
sigemptyset(&p);
sigpending(&p);//获取当前进程信号发生位图,即获取当前进程中所有信号放入信号集p中.
print_sig(&p);
sleep(1);
if( count++ == 10 ){
sigprocmask(SIG_SETMASK,&o,NULL);
printf("recover block\n");
sleep(3);
}
}
}
代码2:
#include
#include
#include
#include
#include
int main(){
sigset_t initset;
int i;
sigemptyset(&initset);//初始化信号集合为空集合
sigaddset(&initset,SIGINT);//将SIGINT信号加入到此集合中去
while(1){
sigprocmask(SIG_BLOCK,&initset,NULL);//将信号集合加入到进程的阻塞集合中去
fprintf(stdout,"SIGINT singal blocked/n");
for(i=0;i<10;i++){
sleep(1);//每1秒输出
fprintf(stdout,"block %d/n",i);
}
//在这时按一下Ctrl+C不会终止
sigprocmask(SIG_UNBLOCK,&initset,NULL);//从进程的阻塞集合中去删除信号集合
fprintf(stdout,"SIGINT SINGAL unblokced/n");
for(i=0;i<10;i++){
sleep(1);
fprintf(stdout,"unblock %d/n",i);
}
}
exit(0);
}
执行结果:
SIGINT singal blocked
block 0
block 1
block 2
block 3
block 4
block 5
block 6
block 7
block 8
block 9
在执行到block 3时按下了CTRL+C并不会终止,直到执行到block9后将集合从阻塞集合中移除。
[root@localhost C]# ./s1
SIGINT singal blocked
block 0
block 1
block 2
block 3
block 4
block 5
block 6
block 7
block 8
block 9
SIGINT SINGAL unblokced
unblock 0
unblock 1
由于此时已经解除了阻塞,在unblock1后按下CTRL+C则立即终止。
相关文章推荐
- sigemptyset、sigaddset、sigprocmask的用法 信号未决,信号阻塞 信号的捕捉
- sigprocmask阻塞信号
- sigprocmask和信号阻塞
- 【C】——sigprocmask 阻塞进程信号
- 信号基本操作之sigprocmask阻塞进程
- 进程的信号掩码【sigprocmask(int what,const sigset_t *set,sigset_t *oldset)】
- 那年,一步一步学linux c ---sigprocmask 阻塞进程
- sigprocmask 阻塞进程
- 关于信号sigprocmask
- linux信号(sigprocmask,sigpending)
- Linux signals(二) sigprocmask,sigaction,不可靠信号及实例代码
- 2信号处理之:信号产生原因,进程处理信号行为,信号集处理函数,PCB的信号集,sigprocmask()和sigpending(),信号捕捉设定,sigaction,C标准库信号处理函数,可重入函数,
- 信号相关函数(signal,sigaction,sigprocmask, kill,sigqueue信号发送函数,睡眠函数,计时器函数)
- 信号:signal(), sigaction(), sigaddset(), sigemptyset(), sigismember(), sigprocmask()
- 信号阻塞与屏蔽:SIG_BLOCK, SIG_UNBLOCK, SIG_MASK区别与使用
- C语言学习:信号屏蔽字sigset_t,sigprocmask,sigpending
- linux c编程:信号(三) sigprocmask和sigpending函数
- APUE 程序清单10-11 信号设置和sigprocmask实例
- Unix环境高级编程(阅读笔记)----信号集、信号屏蔽函数sigprocmask
- 等待单个进程信号的正确方法 sigprocmask