Linux进程中信号屏蔽
在linux的进程中可以接收到各种的信号,并且如果你不对信号进行处理,linux中的进程就会采用默认的处理方式处理,比如ctrl-c的信号,进程对它的处理就是终止进程的执行。我们也可以在进程中屏蔽掉某些信号,使进程不去处理这些信号,但其中的SIGKILL和SIGSTOP是不能被阻塞的。
在这里先介绍几个信号的函数:
int sigemptyset(sigset_t *set); // 清空信号集set
int sigfillset(sigset_t *set); // 填满信号集,即让set包含所有的信号
int sigaddset(sigset_t *set, int signo); // 在set中增加signo信号
int sigdelset(sigset_t *set, int signo); // 在set中去掉signo信号
int sigismember(sigset_t *set, int signo); // 信号signo是否在信号集set中
iint sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
若oldset非空,则进程的当前信号屏蔽字通过oldset返回,若set是一个非空指针,看参数how指示如何修改当前信号的屏蔽字,how可以取三个值:
SIG_BLOCK: 按照参数set提供的屏蔽字,屏蔽信号,并将原信号屏蔽保存到oldset中
SIG_UNBLOCK: 按照参数set提供的屏蔽字进行信号的解除屏蔽,针对set中的信号进行解屏蔽
SIG_SETMASK: 按照参数set提供的信号设置重新设置系统信号设置
int sigpending(sigset_t *set); // 该函数返回信号集,该信号通过set参数返回
sigsuspend(sigset_t sigs); // 屏蔽新的信号,原来屏蔽的信号失效。sigsuspend是阻塞函数,对参数信号屏蔽,对参数没有指定的信号不屏蔽,
当信号处理函数调用完毕,sigsuspend函数返回并恢复旧的屏蔽信号。(理解: sigsuspend=pause()+指定屏蔽的信号)
示例代码如下:
/** * 利用sigsuspend实现执行任务中断处理 * signal_mask_demo.c * Created on: Oct 12, 2016 * Author: zhangming */ #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> void handle(int s) { printf("外部用户中断处理...\n"); sleep(5); printf("外部用户中断处理结束...\n"); } main() { int sum = 0; int i; sigset_t sigs, sigt, sigu; sigemptyset(&sigs); sigemptyset(&sigt); sigemptyset(&sigu); sigaddset(&sigs, SIGINT); sigaddset(&sigs, SIGUSR1); signal(SIGINT, handle); sigprocmask(SIG_BLOCK, &sigs, 0); for (i = 0; i < 10; i++) { printf("正在拷贝电影<%d>!\n", i); sleep(7); //模拟业务处理时间比较长 printf("电影拷贝完毕<%d>!\n", i); sigpending(&sigu); if (sigismember(&sigu, SIGINT)) { /** * 使原来屏蔽信号sigs无效,开放原来信号,使新的信号sigq屏蔽, * 当某个信号处理函数处理完毕,sigsuspend恢复原来屏蔽信号sigs,返回 */ sigsuspend(&sigt); } } printf("所有电影拷贝完毕\n", sum); printf("over!\n"); sigprocmask(SIG_UNBLOCK, &sigs, 0); }

浙公网安备 33010602011771号