信号集

基本概念

概念: 信号产生处于未决状态, 进程收到信号之后, 信号被放入未决信号集; 放入未决信号集的信号等待处理之前, 先判断阻塞信号集中该信号对应的标志位是否为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
*/
posted @ 2019-04-19 21:23  张飘扬  阅读(227)  评论(0编辑  收藏  举报