IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Linux进程信号~详解 -> 正文阅读

[系统运维]Linux进程信号~详解

一.信号的概念

信号是进程之间事件异步通知的一种方式,属于软中断
告诉有这样一个信号,但是这个信号的具体处理方式以及什么时候处理由进程决定,所以是软中断。

二.信号的种类

kill —l

可以罗列出所有信号(总共定义了62个信号)
在这里插入图片描述
没有32,33号信号

  • 非实时信号(又称非可靠信号)
    特点:信号可能会丢失 1~31

  • 实时信号(又称可靠信号)
    特点:信号不会丢失 33~64

三.信号的产生

1.硬件产生

kill命令向进程发送信号kill -[信号值] [pid]

  • ctrl +c :2号信号 SIGINT
    键盘按下ctrl +c 结束一个进程的时候,其实是进程收到了2号信号。2号信号导致进程的退出
  • ctrl +z:20号信号SIGTSTP
    在这里插入图片描述在这里插入图片描述
    使用ctrl +z会使一个程序进入暂停状态T;
  • ctrl +|
    在这里插入图片描述

2.软件产生

  • kill函数int kill(pid_t pid,int sig);
    pid:进程号,要给哪个进程发送信号,则填写哪个进程的进程号
    sig:要发送信号的值
    在这里插入图片描述

  • raiseint raise(int sig);
    谁调用则给谁发送信号。该函数的实现也是调用kill函数

int raise(int sig){
	return kill(gitpid(),sig);
}

在这里插入图片描述

3.扩展:崩溃程序收到的信号

  • 引用空指针,野指针,垂悬指针(收到11号信号)
  • 内存访问越界(收到11号信号)
  • 除0(收到8号信号)
  • double free(收到6号信号)

我们在C/C++当中除零,内存越界等异常,在系统层面上,是被当成信号处理的。

四.信号的处理方式

man 7 signal  查看

在这里插入图片描述

1.默认处理方式

SIG_DFL:操作系统当中已经定义信号的处理方式了
2–>终止程序
11—>终止程序,并且产生核心转储文件

2.忽略处理方式

SIG_IGN:该信号为忽略处理
进程收到忽略处理信号后,不进行处理

SIGCHLD 17号信号

子进程先于父进程退出,子进程退出的时候会给父进程发送SIGCHLD,而父进程接收到这个信号后,是忽略处理的,导致父进程没有回收到子进程的退出状态信息,从而子进程变成僵尸进程。

3.自定义处理方式

程序员也可以更改信号的处理方式,定义一个函数,当进程收到该信号的时候,调用自己写的函数

五.信号的注册

一个信号收一个信号的过程叫做信号的注册
信号的注册和信号的注销不是一个过程,是两个独立的过程

内核当中信号注册位图和sigqueue 队列的了解
在这里插入图片描述
操作系统内部并没有将sig[] 当做数组使用,而是当做位图使用
在这里插入图片描述
总结:

  1. 信号注册时位图更改为1,添加sigqueue节点和sigqueue队列
  2. 信号注册时,会将信号对应的比特位从0修改为1,表示当前进程收到了该信号
  3. 需要在sigqueue队列中添加sigqueue节点,队列在操作系统内核中的本质是一个双向链表(先进先出

两种信号注册的区别

  • 非实时信号注册
    第一次注册:修改sig位图(从0到1),修改sigqueue队列
    第二次注册相同信号:修改sig位图(从1到1),并不会添加sigqueue节点
  • 非实时信号注册
    第一次注册:修改sig位图(从0到1),修改sigqueue队列
    第二次注册相同信号:修改sig位图(从1到1),添加sigqueue节点到sigqueue队列当中

六.信号的注销

  • 非实时信号
    将信号对应的sig位图当中的比特位由1改为0
    将对应信号的sigqueue节点进行出队操作

  • 实时信号
    将对应的信号的sigqueue节点进行出队操作
    判断sigqueue队列当中是否还有相同信号的sigqueue节点
    有:则比特位不变 没有:比特位由1改为0

七.信号的自定义处理方式

程序员自己定义某一个信号的处理方式

1.实现函数

函数sighandler_t signal(int signum,sighandler_t handler);

  • signum:信号值
  • handler:更改为的函数处理,接收一个函数地址,函数指针typedef void(*sighandler_t)(int);
    注意:
    在调用singnal函数的时候,给第二个参数传递函数地址的时候并没有调用传递的函数,而是等到进程收到某个信号的时候,才回调刚刚注册的函数。
    9号信号SIGKILL(强杀)不能被自定义处理。

函数int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);

  • signum:信号值
  • act:将信号的处理方式改为act
  • oldact:原来信号的处理方式
#include<stdio.h>
#include<unistd.h>
#include<signal.h>


struct sigaction oldact;
 
void sigcallback(int sig)
{
    printf("sig num is %d\n",sig);
    sigaction(2,&oldact,NULL);
}


int main(){
    //调用sigaction函数,自定义2号信号的处理方式
    //定义struct sigaction 机构体对象
    struct sigaction act;
    act.sa_handler=sigcallback;
    //将act.sa_mask内部清0,防止后续误导进程收到某些信号
     sigemptyset(&act.sa_mask);

     sigaction(2,&act,&oldact);

     while(1){
    sleep(1);
     }
return 0;
}

主函数中调用sigaction将2号信号的处理方式改为调用sigcallback,在sigcallback函数中重新将2号信号处理方式改回来
现象:运行程序第一次按下crrl+c运行sigcallback函数内部代码,第二次按下结束进程
在这里插入图片描述

2.原理:内核中的代码

在这里插入图片描述

八.信号的捕捉流程

1.过程

在这里插入图片描述

2.信号的处理时机

当从内核态切换回用户态的时候,会调用do_signal函数处理信号
do_signal:判断当前信号是否被阻塞
有:处理该信号(信号的处理方式:默认,忽略,自定义)
没有:直接返回用户态

3.不同的处理方式

默认,忽略:直接在内核中就结束处理
自定义处理:

  • 执行用户自定义的处理函数(用户空间)
  • 执行sigreturn()再次回到操作系统内核(内核空间)
  • 再次调用 会调回do_signal函数处理信号
  • 调用sys_sigreturn函数回到用户态,继续执行代码

4.常见进入内核的方式

  • 调用系统调用函数
  • 内存访问越界,访问空指针
  • 调用库函数

九.信号的阻塞

信号的阻塞并不会影响信号的注册,而是在进程收到信号的时候,由于阻塞,暂时不处理该信号

1.内核代码

  struct task_struct{
.........
        sigset_t blocked;(位图)
........
}

当需要阻塞一个信号的时候,将信号对应的比特位设置为1
0:不阻塞
1:阻塞

当加上信号阻塞后,理解信号的处理

  • 进入内核,返回之前,会调用do_signal函数处理该信号
  • 有信号要处理的时候,先判断信号是否阻塞,有阻塞则不处理,无阻塞则处理信号

2.函数接口

函数int sigprocmask(int how,sigset_t *set, sigset_t *oldset);

  • how:想让sigprocmask做什么事情
    SIG_BLOCK:设置某个信号进入阻塞状态
    SIG_UNBLOCK:设置某个信号进入非阻塞状态
    SIG_SETMASK:用第二个参数‘set’,替换原理的阻塞位图
  • set:设置新的阻塞位图
  • oldset:原理老的阻塞位图

原理解析:

  • 当how为SIG_BLOCK时,函数会根据set,计算新的阻塞位图方式为block(new)=block(old) | set
  • 当how为SIG_UNBLOCK时block(new)=block(old) & ~set
  • 当how为SIG_SETMASK时block(new)=set

9号信号和19号信号不能被阻塞

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-04-04 12:51:11  更:2022-04-04 12:51:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 23:22:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码