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 系统调用接口

相关推荐
傻啦嘿哟41 分钟前
Python正则表达式:用“模式密码“解锁复杂字符串
linux·数据库·mysql
浪裡遊2 小时前
Linux常用指令
linux·运维·服务器·chrome·功能测试
SugarPPig3 小时前
PowerShell 查询及刷新环境变量
服务器
段ヤシ.3 小时前
银河麒麟(内核CentOS8)安装rbenv、ruby2.6.5和rails5.2.6
linux·centos·银河麒麟·rbenv·ruby2.6.5·rails 5.2.6
深夜情感老师5 小时前
centos离线安装ssh
linux·centos·ssh
我的作业错错错5 小时前
搭建私人网站
服务器·阿里云·私人网站
王景程5 小时前
如何测试短信接口
java·服务器·前端
微网兔子6 小时前
伺服器用什么语言开发呢?做什么用什么?
服务器·c++·后端·游戏
夸克App7 小时前
实现营销投放全流程自动化 超级汇川推出信息流智能投放产品“AI智投“
运维·人工智能·自动化
Rainbond云原生7 小时前
83k Star!n8n 让 AI 驱动的工作流自动化触手可及
运维·人工智能·自动化