ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

linux 信号处理 三 (信号集的使用)

2020-11-26 10:33:11  阅读:258  来源: 互联网

标签:set handle 信号处理 阻塞 信号 linux 掩码 include


sigprocmask系统调用

 

使用条件:

1、有时候不希望在接到信号时就立即停止当前执行,去处理信号,同时也不希望忽略该信号,而是延时一段时间去调用信号处理函数。这种情况是通过阻塞信号实现的。

2、信号阻塞和忽略信号的区别。

阻塞的概念和忽略信号是不同的。操作系统在信号被进程解除阻塞之前不会讲信号传递出去,被阻塞的信号也不会影响进程的行为,信号只是暂时被阻止传递。当进程忽略一个信号时,信号会被传递出去但进程会将信号丢弃。

3、信号阻塞系统调用,它们的都起到阻塞的作用,它们不是协作使用的。


功能描述:

  设定对信号屏蔽集内的信号的处理方式(阻塞或不阻塞)。


用法:


#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

参数:

how:用于指定信号修改的方式,可能选择有三种

SIG_BLOCK    //将set所指向的信号集中包含的信号加到当前的信号掩码中。即信号掩码和set信号集进行或操作。

SIG_UNBLOCK  //将set所指向的信号集中包含的信号从当前的信号掩码中删除。即信号掩码和set进行与操作。

SIG_SETMASK  //将set的值设定为新的进程信号掩码。即set对信号掩码进行了赋值操作。

 

set:为指向信号集的指针,在此专指新设的信号集,如果仅想读取现在的屏蔽值,可将其置为NULL。

oldset:也是指向信号集的指针,在此存放原来的信号集。可用来检测信号掩码中存在什么信号。

返回说明:

成功执行时,返回0。失败返回-1,errno被设为EINVAL。

复制代码
 1 #include <stdio.h>
 2 #include <unistd.h>
 3 #include <signal.h>
 4 #include <stdlib.h>
 5 
 6 static void sig_int(int signo)
 7 {
 8     int i;
 9     printf("caught SIGQUIT\n");
10     for(i=0;i<=5;i++)
11     {
12         printf("signal handle %d\n",i);
13         sleep(1);
14     }
15     signal(SIGQUIT, SIG_DFL);//将SIGQUIT的动作设为缺省值
16 }
17 int main()
18 {
19     sigset_t newmask;
20     sigset_t oldmask;
21     sigset_t pendmask;
22     int i=0;
23     
24     //信号量捕捉函数,捕捉到SIGINT,跳转到函数指针sig_int处执行
25     signal(SIGINT, sig_int);
26     
27     //初始化信号量集
28     sigemptyset(&newmask);
29     
30     //将SIGQUIT添加到信号量集中
31     sigaddset(&newmask, SIGQUIT);
32     
33     //将newmask中的SIGQUIT阻塞掉,并保存当前信号屏蔽字到Oldmask
34     sigprocmask(SIG_BLOCK, &newmask, &oldmask);
35     printf("sigprocmask SIGQUIT finish\n");    
36     //休眠5秒钟,这里做说明:在5s休眠期间,任何SIGQUIT信号都会被阻塞,如果在5s内收到任何键盘的quit信号
37     //则此时会把这些信息存在内核的队列中,等待5s结束后,可能要处理此信号。
38     for(i=0;i<=5;i++)
39     {
40         sleep(1);
41         printf("block %d\n",i);
42     }
43     
44     //检查哪些信号是悬而未决的
45     sigpending(&pendmask);
46     
47     //检查SIGQUIT是否悬而未决的。所谓悬而未决,是指SIGQUIT被阻塞还没有被处理
48     if (sigismember(&pendmask, SIGQUIT))
49     {
50         printf("\nSIGQUIT pending\n");
51     }
52     
53     //恢复被屏蔽的信号SIGQUIT
54     sigprocmask(SIG_SETMASK, &oldmask, NULL);
55     
56     /**开始处理信号,调用信号处理函数*/ 
57     printf("SIGQUIT unblocked\n");
58     
59     sleep(5);//再次休眠5秒钟
60     
61     return (0);
62 
63 }
复制代码

 

 所谓阻塞时间为:“sigprocmask(SIG_BLOCK, &newmask, &oldmask)”设置阻塞到“sigprocmask(SIG_SETMASK, &oldmask, NULL)”解除阻塞的整个时间,当然这期间发生了信号处理函数,也将阻塞信号集中的信号。

以上示例是Linux redhat,
执行结果是
$./a.out

sigprocmask SIGQUIT finish       //信号集添加了“SIGQUIT ”信号
block 0
^Ccaught SIGQUIT         //发生了信号处理函数
signal handle 0
signal handle 1
^\signal handle 2          //信号处理函数过程中信号集中的信号仍然阻塞
signal handle 3
signal handle 4
signal handle 5
block 1
^\block 2              //信号集中的信号阻塞
block 3
block 4
block 5

SIGQUIT pending
退出 (核心已转储)

 

【sigpending系统调用】

#include<signal.h>

int sigpending(sigset_t *set);

sigpending函数返回信号集,其中的各个信号对于调用进程是堵塞的而不能递送,因而也一定是未决的。该信号集通过set参数返回。

标签:set,handle,信号处理,阻塞,信号,linux,掩码,include
来源: https://www.cnblogs.com/lidabo/p/14040976.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有