信号集
目录
基本概念
概念: 信号产生处于未决状态, 进程收到信号之后, 信号被放入未决信号集; 放入未决信号集的信号等待处理之前, 先判断阻塞信号集中该信号对应的标志位是否为1(不处理), 0为处理; 当阻塞信号集对应的标准位为0时, 该信号被处理
未决信号集: 没有被当前进程处理的信号集
阻塞信号集: 将某个信号放到阻塞信号集, 这个信号就不会被进程处理; 阻塞接触之后, 信号被处理
自定义信号集: 通过自定义信号集来设置内核中的信号集
基础API
sigemptyset
int sigemptyset(sigset_t *set);
将set集合置空
sigfillset
int sigfillset(sigset_t *set);
将所有信号加入set集合
sigaddset
int sigaddset(sigset_t *set, int signum);
将signum信号加入set集合
sigdelset
int sigdelset(sigset_t *set, int signum);
从set集合中溢出signo信号
sigismember
int sigismember(const sigset_t *set, int signum);
判断信号是否存在
sigprocmask
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
屏蔽and接触信号屏蔽, 将自定义信号集设置给阻塞信号集
how: SIG_BLOCK(mask = mask | set), SIG_UNBLOCK(mask & ~mask), SIG_SETMASK(mask = mask)
sigpending
int sigpending(sigset_t *set);
读取当前进程的未决信号集
set: 将内核的未决信号集写入set
示例程序
查看内核中的未决信号集
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <signal.h>
int main(int argc, const char *argv[]) {
// 每隔1s读一次内存中的未决信号集
while (1) {
sigset_t pendset;
sigpending(&pendset);
// 1-31信号判断
int i = 0;
for (i = 1; i < 32; ++i) {
if (sigismember(&pendset, i)) {
printf("1");
}
else {
printf("0");
}
}
printf("\n");
sleep(1);
}
return 0;
}
信号实时捕捉
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <signal.h>
int main(int argc, const char *argv[]) {
// 手动屏蔽信号
// 自定义信号集合
sigset_t myset;
// 清空集合
sigemptyset(&myset);
// 添加要阻塞的信号
sigaddset(&myset, SIGINT); // Ctrl + c
sigaddset(&myset, SIGQUIT); // Ctrl + 反斜杠
sigaddset(&myset, SIGKILL); // 实际没有被阻塞, 9号信号不能被阻塞
// 把自定义信号集设置给内核
sigprocmask(SIG_BLOCK, &myset, NULL);
// 每隔1s读一次内存中的未决信号集
while (1) {
sigset_t pendset;
sigpending(&pendset);
// 1-31信号判断
for (int i = 1; i < 32; ++i) {
if (sigismember(&pendset, i)) {
printf("1");
}
else {
printf("0");
}
}
printf("\n");
sleep(1);
}
return 0;
}
/*可发送kill结束进程
0000000000000000000000000000000
^C0100000000000000000000000000000
0100000000000000000000000000000
^\0110000000000000000000000000000
0110000000000000000000000000000
[1]+ Killed ./a.out
Killed
*/