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 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 【进程通信】Signal信号 -> 正文阅读

[系统运维]【进程通信】Signal信号

信号(signal)

??软中断信号(signal,又简称为信号)是Linux下用来在进程间传递消息的方式之一,也是进程间唯一的异步通信方式。从命名中可以看出信号的实质很像中断。进程间可以通过调用kill库函数发送软中断信号,Linux内核也可能给进程发送信号,用以告知该进程发生了某个异步事件。

??注意,信号只用来告知进程发生了某个异步事件,并不用来传递数据。进程收到信号后会有三种处理方式:

  • 忽略,不做任何处理
  • 执行预先设置的处理函数(就像中断服务程序一样)
  • 采用系统的默认操作,大部分是终止进程

?

信号的来源

  1. 用户

    一般是键盘的输入会作为信号发送给进程,比如:Ctrl + C 发送SIGINT信号给进程,默认动作为终止进程;Ctrl + \ 发送SIGQUIT信号给进程,默认动作为终止进程并进行内核映像转储(core dump)

  2. 内核

    当进程执行出错时,内核给进程发送一个对应信号,例如:非法内存引用、浮点数溢出、执行非法指令

  3. 进程

    C++的kill库函数用于进程间发送信号

?

信号的类型

信号名信号值默认处理动作发出信号的原因
SIGINT2终止进程键盘中断Ctrl+c
SIGQUIT3终止进程并进行内核映像转储键盘的退出键被按下
SIGKILL9终止进程,并且不能被捕获、忽略采用kill -9 进程编号 强制杀死程序。
SIGSEGV11终止进程并进行内核映像转储无效的内存引用
SIGTERM15终止进程采用“kill 进程编号”或“killall 程序名”通知程序。
SIGCHLD20,17,18忽略此信号子进程结束信号

PS:

? 内核映像转储(core dump),内核映像转储是指将进程数据在内存的映像和进程在内核结构中的部分内容以一定格式转储到文件系统,并且进程退出执行,这样做的好处是为程序员 提供了方便,使得他们可以得到进程当时执行时的数据值,允许他们确定转储的原因,并且可以调试他们的程序。

?

信号的捕获处理

#include <signal.h>
sighandler_t signal(int signum, sighandler_t handler)
//signum 表示信号的编号
    
//handler 表示信号的处理方式,有三种:
    1. SIG_IGN:忽略改信号,不作为
    2. SIG_DFL:恢复该信号的默认处理方法
    3. 自定义处理函数,注意函数参数为 (int signum)

?

信号的发送

int kill(pid_t pid, int sig)
//pid 目标进程号,有三种情况:
    1. pid>0 将信号sig传给号为pid的进程
    2. pid=0 将信号sig传给同进程组的所有进程(包括自己),常用于父进程给子进程发送信号
    3. pid=-1 将信号广播到系统内所有进程,例如系统关机时向所有登录窗口广播关机信息
    
//sig 被发送的信号编号

?

信号的应用

屏蔽信号

??通常为了程序不被干扰,程序开头通常会屏蔽所有信号,然后再用signal函数对关心的信号设置相应的处理方式。

for(int i=0; i<100; i++) signal(i, SIG_IGN);

?

搞点好玩的

??改变信号 SIGINTSIGTERM的捕获处理,设计一个 ctrl+Ckill 都杀不掉的进程:

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

void func(int sig)
{
    if (sig == SIGINT)
        printf("\b\b杀不死,哈哈哈哈。\n");
    else if (sig == SIGTERM)
        printf("还是杀不死,哈哈哈哈。\n");
}

int main()
{
    for (int ii = 0; ii < 100; ii++)
        signal(ii, SIG_IGN); // 屏蔽全部的信号

    signal(SIGINT, func);
    signal(SIGTERM, func); // 设置SIGINT和SIGTERM的处理函数

    while (1);
}

效果:

使用Ctrl+C 尝试关掉进程:

image-20211023215258482

ps -ef | grep signal 找到其进程号,尝试用 kill 直接干掉:

image-20211023215522014 image-20211023215427407

可以看见,kill + 进程号killall + 进程名 对它都无效,那改怎么杀死这个进程呢?如图,用 kill -9 进程号

image-20211023215647601 image-20211023215658471

因为kill -9 进程号 发送的信号是 SIGKILL,这个信号无法被捕获或忽略,能够快准狠杀掉进程

?

使系统休眠

这个是我尝试用 kill() 函数向系统所有进程发送 SIGKILL 信号后发现的,当然是在虚拟机上,我可不敢在主机上这样搞:

#include <stdio.h>
#include <signal.h>

int main()
{
    kill(-1, SIGKILL);
}

效果是虚拟机进入休眠,输入密码后能再进入,原以为会直接关机呢

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-10-24 15:13:03  更:2021-10-24 15:13:39 
 
开发: 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 20:23:10-

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