基于linux下的高并发服务器开发(第二章)- 2.24 信号集及相关函数

1.用户通过键盘 Ctrl + C, 产生2号信号SIGINT (信号被创建)

**2.信号产生但是没有被处理 (未决)

  • 在内核中将所有的没有被处理的信号存储在一个集合中 (未决信号集)
  • SIGINT信号状态被存储在第二个标志位上
  • 这个标志位的值为0, 说明信号不是未决状态
  • 这个标志位的值为1, 说明信号处于未决状态
    3.这个未决状态的信号,需要被处理,处理之前需要和另一个信号集(阻塞信号集),进行比较
  • 阻塞信号集默认不阻塞任何的信号
  • 如果想要阻塞某些信号需要用户调用系统的API**

**4.在处理的时候和阻塞信号集中的标志位进行查询,看是不是对该信号设置阻塞了

  • 如果没有阻塞,这个信号就被处理
  • 如果阻塞了,这个信号就继续处于未决状态,直到阻塞解除,这个信号就被处理**

以下信号集相关的函数都是对自定义的信号集进行操作。

int sigemptyset(sigset_t *set);

- 功能:清空信号集中的数据,将信号集中的所有的标志位置为0

- 参数:set,传出参数,需要操作的信号集

- 返回值:成功返回0, 失败返回-1

int sigfillset(sigset_t *set);

- 功能:将信号集中的所有的标志位置为1

- 参数:set,传出参数,需要操作的信号集

- 返回值:成功返回0, 失败返回-1

int sigaddset(sigset_t *set, int signum);

- 功能:设置信号集中的某一个信号对应的标志位为1,表示阻塞这个信号

- 参数:

- set:传出参数,需要操作的信号集

- signum:需要设置阻塞的那个信号

- 返回值:成功返回0, 失败返回-1

int sigdelset(sigset_t *set, int signum);

- 功能:设置信号集中的某一个信号对应的标志位为0,表示不阻塞这个信号

- 参数:

- set:传出参数,需要操作的信号集

- signum:需要设置不阻塞的那个信号

- 返回值:成功返回0, 失败返回-1

int sigismember(const sigset_t *set, int signum);

- 功能:判断某个信号是否阻塞

- 参数:

- set:需要操作的信号集

- signum:需要判断的那个信号

- 返回值:

1 : signum被阻塞

0 : signum不阻塞

-1 : 失败

cpp 复制代码
/*
    以下信号集相关的函数都是对自定义的信号集进行操作。

    int sigemptyset(sigset_t *set);
        - 功能:清空信号集中的数据,将信号集中的所有的标志位置为0
        - 参数:set,传出参数,需要操作的信号集
        - 返回值:成功返回0, 失败返回-1

    int sigfillset(sigset_t *set);
        - 功能:将信号集中的所有的标志位置为1
        - 参数:set,传出参数,需要操作的信号集
        - 返回值:成功返回0, 失败返回-1

    int sigaddset(sigset_t *set, int signum);
        - 功能:设置信号集中的某一个信号对应的标志位为1,表示阻塞这个信号
        - 参数:
            - set:传出参数,需要操作的信号集
            - signum:需要设置阻塞的那个信号
        - 返回值:成功返回0, 失败返回-1

    int sigdelset(sigset_t *set, int signum);
        - 功能:设置信号集中的某一个信号对应的标志位为0,表示不阻塞这个信号
        - 参数:
            - set:传出参数,需要操作的信号集
            - signum:需要设置不阻塞的那个信号
        - 返回值:成功返回0, 失败返回-1

    int sigismember(const sigset_t *set, int signum);
        - 功能:判断某个信号是否阻塞
        - 参数:
            - set:需要操作的信号集
            - signum:需要判断的那个信号
        - 返回值:
            1 : signum被阻塞
            0 : signum不阻塞
            -1 : 失败

*/
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

int main(){
    // 创建一个信号集
    sigset_t set;

    //清空信号集的内容
    sigemptyset(&set);
    
    //判断 SIGINT 是否在信号集 set里
    int ret = sigismember(&set,SIGINT);
    if(ret == 0){
        printf("SIGINT 不阻塞\n");
    }else if(ret == 1){
        printf("SIGINT 阻塞\n");
    }else if(ret == -1){
        perror("SIGINT");
        exit(0);
    }

    //添加几个信号到信号集中
    sigaddset(&set,SIGINT);
    sigaddset(&set,SIGQUIT);

    //判断SIGINT是否在信号集中
    ret = sigismember(&set,SIGINT);
    if(ret == 0){
        printf("SIGINT 不阻塞\n");
    }else if(ret == 1){
        printf("SIGINT 阻塞\n");
    }else if(ret == -1){
        perror("SIGINT");
        exit(0);
    }

    //判断SIGQUIT是否在信号集中
    ret = sigismember(&set,SIGQUIT);
    if(ret == 0){
        printf("SIGQUIT 不阻塞\n");
    }else if(ret == 1){
        printf("SIGQUIT 阻塞\n");
    }else if(ret == -1){
        perror("SIGQUIT");
        exit(0);
    }

    //从信号集中删除一个信号
    sigdelset(&set,SIGQUIT);

    //判断SIGQUIT是否在信号集中
    ret = sigismember(&set,SIGQUIT);
    if(ret == 0){
        printf("SIGQUIT 不阻塞\n");
    }else if(ret == 1){
        printf("SIGQUIT 阻塞\n");
    }else if(ret == -1){
        perror("SIGQUIT");
        exit(0);
    }

    return 0;
}
相关推荐
齐齐大魔王35 分钟前
linux-僵死进程处理
linux·运维·服务器
HackTwoHub3 小时前
AI大模型网关存在SQL注入、附 POC 复现、影响版本LiteLLM 1.81.16~1.83.7(CVE-2026-42208)
数据库·人工智能·sql·网络安全·系统安全·网络攻击模型·安全架构
wuminyu3 小时前
专家视角看Java字节码加载与存储指令机制
java·linux·c语言·jvm·c++
l1t3 小时前
DeepSeek总结的DuckLake构建基于 SQL 原生表格式的下一代数据湖仓
数据库·sql
KmSH8umpK4 小时前
Redis分布式锁从原生手写到Redisson高阶落地,附线上死锁复盘优化方案进阶第八篇
数据库·redis·分布式
.小小陈.4 小时前
Linux 线程概念与控制:从底层原理到实战应用
linux·运维·jvm
网络工程小王4 小时前
【LangChain 大模型6大调用指南】调用大模型篇
linux·运维·服务器·人工智能·学习
TDengine (老段)4 小时前
从施工监测到运营预警,桥科院用 TDengine 提升桥梁数据管理能力
大数据·数据库·物联网·时序数据库·tdengine·涛思数据
wangbing11254 小时前
各linux版本的包管理命令
linux·运维·服务器
Joseph Cooper4 小时前
Linux/Android 跟踪技术:ftrace、TRACE_EVENT、atrace、systrace 与 perfetto 入门
android·linux·运维