Linux 信号

目录

1.什么是信号

2.信号的产生

处理信号的常见方式:

如何理解这些组合键是如何变成信号的?

信号发送本质​编辑

信号的种类

​编辑

3.信号处理常见方式概览

4.产生信号

5.信号其他相关常见概念

​编辑

6.捕捉信号

signal函数:

7.可重入函数

8.一些题


1.什么是信号

本质是一种通知机制,用户or操作系统通过发送一定的停号,通知进程,某些事件已经发生,你可以在后续进行处理

1.1.结合进程,分析信号

a.进程要分析信号,必须要识别信号即,进程要接收并且要具备其如何处理的动作。

b.进程如何识别信号呢?通过程序员设置的方式让进程去识别。

c.信号的产生是随机的,所以进程的处理方式可能不是立即处理,而是将信号存储起来,在合适的场合处理。

d.进程会降临是信号进行存储,方便之后的处理。

e.一般而言,信号的产生相对于进程来说是异步的

2.信号的产生

通过键盘的组合键产生

比如:通过Ctrl+c终止进程,是向目标进程发送2号信号,这就是一种通过键盘向进程发送信号,让进程退出了。

处理信号的常见方式:

默认;忽略;自定义(捕捉信号)一共有这三种处理方式。

如何理解这些组合键是如何变成信号的?

键盘的工作方式是通过中断的方式进行的,OS解释组合键,然后在进程列表中查找,找到前台运行的进程,OS将信号写入当前的进程结构中的位图中。

信号发送本质

信号的种类

3.信号处理常见方式概览

1. 忽略此信号。
2. 执行该信号的默认处理动作。
3. 提供一个信号处理函数,要求内核在处理该信号时切换到用户态执行这个处理函数,这种方式称为捕捉 (Catch)一个信号。

4.产生信号

通过终端按键产生信号
调用系统函数向进程发信号
由软件条件产生信号
硬件异常产生信号

5.信号其他相关常见概念

实际执行信号的处理动作称为信号递达(Delivery)
信号从产生到递达之间的状态,称为信号未决(Pending)。
进程可以选择阻塞 (Block )某个信号。
被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作.
注意,阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作。

6.捕捉信号

先思考一个问题:信号是什么时候被处理的

首先,不是立即被处理的。而是在合适的时候,这个合适的时候,具体指的是进程从用户态切换回内核态时进行处理。

用户态: 处于⽤户态的 CPU 只能受限的访问内存,用户的代码,并且不允许访问外围设备,权限比较低。
内核态: 处于内核态的 CPU 可以访问任意的数据,包括外围设备,⽐如⽹卡、硬盘等,权限比较高。
注意: 操作系统中有一个cr寄存器来记录当前进程处于何种状态

signal函数:

signal(int signum, sighandler_t handler);

第一个参数为信号,可以是信号的编号,也可以是信号的名称,第二个参数是一个回调函数,通过回调函数处理信号,可以为默认,忽略,自定义。默认和忽略 所对应的参数名称为:SIG_DFL,SIG_IDO。自定义的参数需要自己写回调函数去完成。通过回调的方式,去修改对应的信号捕捉方法。

cpp 复制代码
#include <stdio.h>
#include <signal.h>

void sigcb(int signal)
{
    printf("触发本次事件的信号值:%d\n", signal);
}

int main()
{
    // 设置SIGINT信号的处理函数为sigcb
    signal(SIGINT, sigcb);

    // 死循环,等待SIGINT信号触发
    while (1)
    {
    }

    return 0;
}
//当您运行这段代码后,在终端中按下Ctrl+C(发送SIGINT信号),"sigcb"函数将被调用,并打印出触发本次事件的信号值。

7.可重入函数

函数的重入指的是一个函数在不同执行流中同时进入运行,其中不可重入指的是一旦重入就有可能会出问题,而可重入就是不管怎么重入都不会有特殊影响

在一个函数中若对全局变量进行了原子操作,则这个函数一定是可重入的

如果一个函数符合以下条件之一则是不可重入的:
调用了malloc或free,因为malloc也是用全局链表来管理堆的。
调用了标准I/O库函数。标准I/O库的很多实现都以不可重入的方式使用全局数据结构

8.一些题

自定义信号捕捉函数 signal函数 sigaction函数

SIGSTOP/SIGKILL信号无法被阻塞,无法被自定义,无法被忽视

Ctrl+C会向当前终端的前台进程发送SIGINT信号,中断正在运行在前台的程序

Ctrl+Z会使当前终端的前台进程进入停止态而不是退出

raise接口可以向当前调用进程发送任意信号

未决信号是在从程序运行在内核态返回用户态的时候进行处理

只有自定义处理方式的信号会在用户态进行处理

自定义处理方式的信号会在执行完信号捕捉函数后先返回内核态

1. 一个进程无法被kill杀死的可能有哪些?

A.这个进程阻塞了信号

B.用户有可能自定义了信号的处理方式

C.这个进程有可能是僵尸进程

D.这个进程当前状态是停止状态

都对 ABCD

2.程序运行从用户态切换到内核态的操作:中断/异常/系统调用

I. 整数除以零

II. sin()函数调用

III. read 系统调用

I 会导致程序异常(分母不能为0)

II 库函数并不会引起运行态的切换

III 系统调用接口

相关推荐
九河云34 分钟前
AWS账号注册费用详解:新用户是否需要付费?
服务器·云计算·aws
Lary_Rock39 分钟前
RK3576 LINUX RKNN SDK 测试
linux·运维·服务器
幺零九零零2 小时前
【计算机网络】TCP协议面试常考(一)
服务器·tcp/ip·计算机网络
云飞云共享云桌面3 小时前
8位机械工程师如何共享一台图形工作站算力?
linux·服务器·网络
Peter_chq3 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
一坨阿亮4 小时前
Linux 使用中的问题
linux·运维
dsywws5 小时前
Linux学习笔记之vim入门
linux·笔记·学习
幺零九零零6 小时前
【C++】socket套接字编程
linux·服务器·网络·c++
wclass-zhengge6 小时前
Docker篇(Docker Compose)
运维·docker·容器
李启柱6 小时前
项目开发流程规范文档
运维·软件构建·个人开发·设计规范