本文主要是介绍Linux中如何屏蔽信号,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
本篇文章主要学习Linux的信号处理机制,着重学习屏蔽信号部分。屏蔽信号处理的两种方式类似于信号的捕获,一种方式是直接对其设置,另一种方式是先获得描述符的掩码,然后对其设置操作。
本文主要参考自《嵌入式linux系统使用开发》,作者何永琪,Thanks.
在linux系统中,如何处理某个进程发送的一个特定信号呢?一般来说有三种方式:
1) 忽略信号
2) 屏蔽信号
3) 为该信号添加用户自定义的信号处理函数,从而优先调用,而不使用默认的操作。
一、信号集基本操作函数
本篇文章着重解决第二种方案,如何屏蔽该信号。
在Linux上有一组函数专门用于对信号集进行操作,它们的接口头文件及原型如下:
#include <signal.h>
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set,int signum);
int sigdelset(sigset_t *set,int signum);
int sigismember(const sigset_t *set,int signum);
其中set参数指向要操作的信号集,而signum参数则代表一个指定的信号,各个函数的作用如下:
函数 | 作用 |
---|---|
sigemptyset | 清空信号集,返回0表示成功,-1表示失败 |
sigfillset | 将所有信号加入信号集,返回0表示成功,-1表示失败 |
sigaddset | 将指定信号加入信号集,返回0表示成功,-1表示失败 |
sigdelset | 将指定信号从信号集中去除,返回0表示成功,-1表示失败 |
sigismember | 判断一个指定的信号是否在信号集中,返回1表示在信号集中,0表示不在信号集中,-1表示有错误发生。 |
有了这些函数,编程时就没必要直接对sigset_t型数据进行操作了,从而也不必知道它的具体含义。一般来说,信号集在使用前需要先用sigemptyset或者sigfillset函数进行初始化,然后调用sigaddset或sigdelset函数增加或去除需要的信号。
二、sigprocmask函数定义
在调用sigaction函数时,可以设置信号处理时需要屏蔽的信号。实际上在代码中也可以直接设置或获取进程的信号掩码。所使用的接口函数如下:
int sigprocmask(int how,const sigset_t *set, sigset_t *oldset);
其各个参数及返回值含义解释如下:
参数 | 作用 |
---|---|
how | 指定操作信号掩码的方式 |
set | 指向用于设置信号掩码的信号集 |
oldset | 用于返回原来的信号掩码 |
返回值 | 0表示成功,-1表示失败 |
sigprocmask函数根据参数how指定的方式,设置当前进程的信号掩码,并把原来的信号掩码保存在参数oldset指向的信号集中返回。
如果set参数为NULL,则不修改信号掩码;如果oldset参数为NULL,则不返回原来的信号掩码。
这里关键要理解参数how的使用。它由如下三个取值:
参数how | 作用 |
---|---|
SIG_BLOCK | 将set参数指向的信号集中的信号加入到信号掩码中 |
SIG_UNBLOCK | 将set参数指向的信号集中的信号从信号掩码中删除 |
SIG_SETMASK | 将set参数指向的信号集中的信号设置为信号掩码 |
三、屏蔽信号的处理
1)屏蔽信号的两种方式
因此,屏蔽某个信号有两种方式,,下面以SIGUSER1为例进行说明:
第一种方式为使用SIG_BLOCK操作方式,代码如下:
sigset_t sigset;
sigemptyset(&sigset);
sigaddset(&sigset,SIGUSER1);
sigprocmask(SIG_BLOCK,&sigset,NULL);
第二种方式为使用SIG_SETMASK操作方式,代码如下:
sigset_t set;
sigprocmask(SIG_SETMASK,NULL,&set); //先得到当前的信号掩码
sigaddset(&set,SIGUSER1);//将要屏蔽的信号加入
sigprocmask(SIG_SETMASK,&set,NULL);
2)解除屏蔽信号的两种方式
同样,要解除对信号的屏蔽,也有两种方式,仍以SIGUSER1为例进行说明。
第一种方式,使用使用SIG_UNBLOCK操作方式,代码如下:
sigset_t sigset;
sigemptyset(&sigset);
sigaddset(&sigset,SIGUSER1);
sigprocmask(SIG_UNBLOCK,&sigset,NULL);
第二种方式,使用SIG_SETMASK操作方式,代码如下:
sigset_t set;
sigprocmask(SIG_SETMASK,NULL,&set); //先得到当前的信号掩码
sigdelset(&set,SIGUSER1);//将要屏蔽的信号去除
sigprocmask(SIG_SETMASK,&set,NULL);
这篇关于Linux中如何屏蔽信号的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!