信号是事件发生时对进程的通知机制,也称为软中断。发往进程的诸多信号,通常都是源于内核。引发内核为进程产生信号的各类事件如下:
1. 硬件异常
2. 用户键入了能够产生信号的终端特殊字符
3. 发生了软件事件(定时器到期、终端窗口调整等)
针对每个信号,都定义了一个唯一的整数,从1开始顺序展开。以SIGXXX形式的符号名对这些整数做了定义。
信号分为两大类。第一类用于内核向进程通知事件,宫城所谓的传统或者标准信号。linux中标准信号的编号范围是1~31,另一类信号由实时信号构成。
信号到达后,进程可以有如下三种反应:
1. 采取默认行为
2. 忽略信号
3. 指向信号处理器程序
改变信号处置函数:
-
#include <signal.h>
-
void (* signal(int sig, void (*handler)(int)) )(int);
在为signal()指定handler参数时,可以使用如下值来代替函数地址:SIG_DFL或者SIG_IGN
-
#include <signal.h>
-
int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact);
-
/*returns 0 on success, or -1 on error*/
-
struct sigaction{
-
void (*sa_handler)(int);/*Address of handler,可以为SIG_IGN或者SIG_DFL*/
-
sigset_t sa_mask;/*signals blocked during handler invocation, 引发对处理器程序调用的信号将自动添加到进程信号掩码中*/
-
int sa_flags;/*flags controlling handler invocation */
-
void (*sa_restorer)(void);/*not for application use*/
-
};
信号集相关操作如下:
-
#include <signal.h>
-
int sigemptyset(sigset_t *set);
-
int sigfillset(sigset_t *set);
-
/*both return 0 on success, or -1 on error*/
-
int sigaddset(sigset_t *set, int sig);
-
int sigdelset(sigset_t *set, int sig);
-
/*both return 0 on success, or -1 on error*/
-
int sigismember(const sigset_t *set, int sig);
-
/*returns 1 if sig is a member of set, otherwise 0*/
信号掩码:
内核会为每个进程维护一个信号掩码,即一组信号,并将阻塞其针对该进程的传递。如果将阻塞的信号发送给某个进程,那么对该信号的传递将延后,直至从进程信号掩码中移除该信号,从而解出阻塞位置(信号掩码实际属于线程属性,在多线程进程中,每个线程都可以使用pthread_sigmask()函数来独立检查和修改自身信号掩码)
-
#include <signal.h>
-
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
-
/*returns 0 on success, or -1 on error*/
上述函数既可以修改进程的信号掩码,又可以获取现有掩码,或者两者兼具
how取值
|
描述
|
SIG_BLOCK
|
将set指向的信号集合内的信号添加到信号掩码中,与当前掩码集取并
|
SIG_UNBLOCK
|
将set指向的信号机和内的信号在信号掩码中删除
|
SIG_SETMASK
|
将set指向的信号机赋值给信号掩码
|
上述各种情况,若oldset不为空,则其指向一个sigset_t结构缓冲区,用于返回之前的信号掩码
如果想获取信号掩码而又对其不做改动,那么可以将set参数指定为空,这时将忽略how参数
-
#include <signal.h>
-
int sigpending(sigset_t *set);
-
/*returns 0 on success, or -1 on error*/
阅读(7022) | 评论(0) | 转发(1) |