Linux系统编程(四)信号

一、什么是信号?

1、信号的本质

信号在linux中又称为软中断信号,用来通知进程发生了异步事件。进程收到信号必须停止,直到处理完信号后再执行下一条指令。

2、信号来源

硬件来源

终端按键产生信号 ,如(Ctrl + c ,Ctrl + z ,Ctrl+\)
硬件异常产生信号, 如(除0操作,非法访问内存(段错误),总线错误)

软件来源

kill命令以及进程之间可以互相通过系统调用kill发送软中断信号

二、常见信号

1.可靠信号和不可靠信号

Linux信号的编号是从1-64,其中32和33空缺,没有对应的信号。通过kill -l 可查看所有的信号
在这里插入图片描述
其中

- 1~31之间的信号叫做非实时信号, 不支持排队, 信号可能会丢失, 也叫做不可靠信号。
- 34~64之间的信号叫做实时信号, 支持排队, 信号不会丢失, 也叫做可靠信号。

2、不可靠信号主要有以下问题:

  • 存在信号丢失的问题(进程收到的信号不作排队处理,相同的信号多次到来会合并为一个)。

3、可靠信号与不可靠信号注册机制

可靠信号注册机制:
内核每收到一个可靠信号都会去注册这个信号,在信号的未决信号链中分配sigqueue结构,因此,不会存在信号丢失的问题。

不可靠信号的注册机制:
而对于不可靠的信号,如果内核已经注册了这个信号,那么便不会再去注册,对于进程来说,便不会知道本次信号的发生。

三、信号处理方式

1.默认动作,默认动作包括:

  1. Term:终止进程
  2. Ign: 忽略信号 (默认即时对该种信号忽略操作)
  3. Core:终止进程,生成Core文件。(查验进程死亡原因, 用于gdb调试)
  4. Stop:停止(暂停)进程
  5. Cont:继续运行进程

2.忽略某个信号,不做任何处理
3.捕捉信号处理

四、信号处理过程

在这里插入图片描述

五、未决信号和阻塞信号

信号的“未决”是一种状态,是信号产生和递送之间的一种状态。信号产生,未决信号集中描述改信号的位会立即变为1,信号处于未决状态。当信号被处理,对应位会变为0;如果信号被阻塞,那么信号的未决状态将保持在1,信号也就无法执行。

六、信号集操作函数

#include <signal.h>
sigset_t set; // typedef unsigned long sigset_t;
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set, int signum);
int sigdelset(sigset_t *set, int signum);
int sigismember(const sigset_t *set, int signum);
函数sigemptyset初始化set所指向的信号集,使其中所有信号的对应bit清零,表示该信号集不包含任何有效信号。函数sigfillset初始化set所指向的信号集,使其中所有信号的对应bit置位,表示该信号集的有效信号包括系统支持的所有信号。注意,在使用sigset_t类型的变量之前,一定要调用sigemptyset或sigfillset做初始化,使信号集处于确定的状态。初始化sigset_t变量之后就可以在调用sigaddset和sigdelset在该信号集中添加或删除某种有效信号。这四个函数都是成功返回0,出错返回-1。sigismember是一个布尔函数,用于判断一个信号集的有效信号中是否包含某种信号,若包含则返回1,不包含则返回0,出错返回-1。

#include <cstdio>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>

void printped(sigset_t* set)
{
    for (int i = 0; i < 32; i++)
    {
        if (sigismember(set, i) == 1)
        {
            printf("1");
        }
        else
        {
            printf("0");

        }
    }
    printf("\n");

}


int main()
{
    sigset_t myset,oldset,set;
    sigemptyset(&myset);
    sigaddset(&myset, SIGQUIT);

    sigprocmask(SIG_BLOCK,&myset,&oldset);
    int ret;
    while(1)
    {
        sleep(1);
        ret = sigpending(&set);
        if (ret == -1)
        {
            
            perror("sigpending error:");
            exit(1);
        }

        printped(&set);
        
    }


   
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chenshida_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值