- 在使用 sigaction 函数处理信号时,可以一并设置进程的信号屏蔽字。但是有单独的函数可以用来设置进程的信号屏蔽字:sigprocmask 函数。
- sigprocmask 函数
#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oset);
参数 how 的取值如下:
名称 | 说明 |
---|---|
SIG_BLOCK | 把参数 set 中的信号添加到信号屏蔽字中 |
SIG_SETMASK | 把信号屏蔽字设置为参数 set 中的信号 |
SIG_UNBLOCK | 从信号屏蔽字中删除参数 set 中的信号 |
- 信号集操作函数
#include <signal.h>
int sigemptyset(sigset_t *set); // 初始化信号集为空
int sigaddset(sigset_t *set, int signo); // 向信号集中添加信号
int sigfillset(sigset_t *set); // 初始化信号集为包含所有已定义的信号
int sigdelset(sigset_t *set, int signo); // 删除给定的信号
int sigismember(sigset_t *set, int signo); // 判断给定信号是否一个信号集的成员。返回值 1:是,0:不是,-1:信号无效
- 将信号加入进程屏蔽字,进程将屏蔽该信号,不做响应!!!(而在 sigaction 信号处理函数中,屏蔽的信号会被排队,并在随后被处理)
代码如下:
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
void handleSig(int);
void main(){
signal(SIGINT, handleSig);
signal(SIGALRM, handleSig);
int res;
sigset_t set;
sigset_t oset;
sigemptyset(&set);
sigemptyset(&oset);
sigaddset(&set, SIGINT); // 添加 SIGINT 信号到信号集
sigaddset(&set, SIGALRM);
res = sigprocmask(SIG_SETMASK, &set, &oset); // 设置进程信号屏蔽字为 set 信号集
while(1){
printf("alive.\n");
sleep(2);
}
}
void handleSig(int sig){
switch(sig){
case SIGINT:
//
printf("got sigint\n");
sleep(10);
printf("got sigint. done.\n");
break;
case SIGALRM:
//
printf("got sigalrm\n");
sleep(10);
printf("got sigalrm. done.\n");
break;
}
}
执行程序,运行结果如下(多次尝试 中断 该进程,进程都没有任何响应):
ubuntu@cuname:~/dev/beginning-linux-programming/test$ gcc -o test6 test6.c
ubuntu@cuname:~/dev/beginning-linux-programming/test$ ./test6
alive.
alive.
^C^C^C^Calive.
^C^C^C^C^C^C^C^C^C^C^C^Calive.
^C^C^C^C^C^C^C^C^C^C^Calive.
^C^C^C^C^C^C^C^C^Calive.
^Calive.
alive.
alive.
Killed