首页 > 系统相关 >linux之进程信号

linux之进程信号

时间:2024-09-22 20:20:24浏览次数:3  
标签:闹钟 int 发送 信号 linux 进程 include

目录

生活例子--提炼基本结论

  信号概念的基本储备

 信号处理

信号产生

信号保存

信号处理


前提知道信号与信号量没有任何关系就比如老婆和老婆饼一样;

生活例子--提炼基本结论

1.  比如说平时定闹钟,我今晚十一点睡觉,睡觉之前定个八点的闹钟,那么在闹钟响了在客观上就是闹钟给我发了个信号;

2.  平时我们过红绿灯,红灯亮了,红黄灯就给我发出一个信号那么此时我就应该等一等 ,绿灯亮了我就可以走了;

3.  在古代我是一个大头兵,远远望见狼烟升起,那么就知道有人要冲出来了就知道要打仗了;

4.  在家里呢,考试没考好,回家的时候发现爸妈往沙发上一座并且脸色阴沉给你传递了一个不好的信号,你此时就知道完蛋了;

1.  信号在生活中随时可以产生

           你也不知道哪一天被分手了等叫做   信号的产生和我是:异步的

2.  你能认识这个信号(红绿灯,狼烟点起,脸色等)

3.  我们知道信号产生了,也知道信号触发了该怎么处理(红绿灯亮了我们知道该怎么办)

           我们把23叫做    你能识别并处理这个信号

4.  我们可能正在做着更重要的事情,只能把到来的信号暂不处理

(就比如我点了个外卖,点好后我在打游戏,突然外卖小哥电话打来了,我就意识到了外卖到了。说明了我能认识外卖小哥电话这个信号,外卖小哥电话产生了我也知道该怎么处理下去拿外卖,但我此时正在做其他的事,那我可能说放楼下或者不管电话)

注意将上述的我换成进程即可;进程识别,进程处理,进程暂不处理等

  信号概念的基本储备

信号:linux系统提供的一种向指定进程发送特定事件的方式;

比如说我要向进程发送9号信号表明要终止进程,比如说要发送19号要暂停一个信号等;

进程收到对应的信号后要对信号做识别和处理;

 信号产生是异步的:信号的到达不依赖于进程的执行状态,可能在进程执行的任何时刻被接收。

 信号处理

 信号的默认动作: 

 进行自定义处理,不想执行默认动作,想让进程收到信号后执行我设定的方法: 



 

#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>

void hander(int sig)
{ // 这个sig就是传递过来的信号编号
    std::cout << "get a sig: " << sig << std::endl;
}

int main()
{
    // 对信号的自定义捕捉,我们只要捕捉一次,后续一直有效
    signal(2, hander); // 对2号信号自定义,名字hander随便起//将来收到2号信号后,未来2号信号将以参数形式传递给hander方法
    //如果一直不产生2号信号,那么hander就永远不会被调用
    //我们也可以对更多的信号进行捕捉
    signal(3, hander);
    signal(4, hander);
    signal(5, hander);
    while (true)
    {
        std::cout << "hello nihao,pid: " <<getpid()<< std::endl;
        sleep(1);
    }
    return 0;
}

  注意:2 SIGINT代表是终止进程,我们平常用的ctrl+c-----给目标进程发送2号信号,所以使用ctrl+c在命令行中使用直接结束进程

  注意:3 SIGQUIT代表是退出进程,我们平常用的ctrl+\-----给目标进程发送3号信号,所以使用ctrl+\在命令行中使用直接退出进程

信号产生

1.  通过kill命令,向指定的进程发送特定的信号

2.  键盘可以产生信号!比如ctrl+c或者ctrl+\

3.  系统调用 

int kill(pid_t pid, int sig);          

kill(getpid(),xxx)==int raise(int sig);给自己发信号,但raise不如kill重要

void abort(void);表示用于立即异常终止当前程序的执行。。abort() 函数会导致程序异常终止。它通常用于在遇到无法恢复的错误时强制停止程序,并产生一个 SIGABRT 信号。

无论用户使用kill命令还是使用键盘打命令还是用户程序调用,但最终发送信号的还是os。

因为发送信号的本质就是修改pcb的位图,只有os才有资格修改; 

 如果我把所有信号都捕捉了呢?

4.  软件条件 

就比如管道的时候,读端关闭而写端一直写---就会发送13 SIGPIPE。在软件层面上因为某些条件不满足,向你的进程发送信号;

这时候介绍alarm函数:

#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>

int main(){
    int cnt=1;
    alarm(1);//设定一秒的闹钟  一秒后收到SIGALRM信号
    while(true){
        std::cout<<"cnt: "<<cnt<<std::endl;
        cnt++;
    }
    return 0;
}

验证IO很慢:

只最后进行IO,不用循环里每次都IO,减少IO次数;

理解闹钟: 

就比如电脑关机了两天,断电断网,但是两天后把电脑打开后右下角的时间还是准确的。

这是因为我们的电脑,在主板上还有一个东西叫纽扣电池,很小,但他一直在维持电脑的时间的,虽然我们关机了,但是电脑中依旧有个电池有电。

闹钟的返回值: 


闹钟设置一次就默认触发一次;

5.  异常 

 除0崩溃:

#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>

void hander(int sig)
{
    std::cout << "get a sig: " << sig << std::endl;
}

int main()
{
    signal(8,hander);
    while (true)
    {
        std::cout << "pid: " << getpid() << std::endl;
        sleep(2);
        int a = 10;
        a /= 0;
        // int *p=nullptr;
        // *p=100;
    }
}

发现循环打印

一直在打印,捕捉到了,说明就是发送了信号。通过man 7 signal查到8号默认终止

野指针崩溃:

#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>

void hander(int sig)
{
    std::cout << "get a sig: " << sig << std::endl;
}

int main()
{
    signal(11, hander);
    int *p = nullptr;
    *p = 100;
    while (true)
    {
        std::cout << "pid: " << getpid() << std::endl;
        sleep(2);
        // int a = 10;
        // a /= 0;
    }
}

发现也是循环打印,但是没在循环里面也循环打印

通过man 7 signal查到11号默认终止

 崩溃了为什么会退出?因为发送的信号默认是终止进程;

可以不退出么?可以,捕捉了异常,但不建议,推荐终止进程;

程序上出现异常最终会体现在硬件上,硬件上的问题又会被os识别到; 

信号保存

信号处理

标签:闹钟,int,发送,信号,linux,进程,include
From: https://blog.csdn.net/yiqizhuashuimub/article/details/142381366

相关文章

  • Linux 中sed命令实现大小写的转换
     001、大写转换为小写[root@PC1test]#lsa.txt[root@PC1test]#cata.txt##测试数据abcDEFHIKLmnOpqM[root@PC1test]#sed's/[A-Z]/\L&/g'a.txt##所有的大写转换为小写abcdef......
  • 进程控制2
    使用waitpid(pid,status,0);填入子进程的pid,阻塞父进程,直到子进程结束了,然后把子进程的pcb结构体的状态码读取出来。使用WIFEXITED(status)判断子进程是否正常退出,WEXITSTATUS(status)读取退出码来判断运行是否正常结束。因为进程结束有3种情况:1.进程正常退出,并正确结束。2......
  • Linux 中实现文本中所有的单词的第一个字符大写,其余字符小写
     001、[root@PC1test]#lsa.txt[root@PC1test]#cata.txt##测试数据afdfeDETFDSSFFdefexkmxnd[root@PC1test]#cata.txt|awk'{for(i=1;i<=NF;i++){$i=toupper......
  • Linux内核源码介绍-内核源码树
    建议点击这里查看个人主页上的最新原文作者:陈孝松主页:chenxiaosong.com哔哩哔哩:陈孝松课程:chenxiaosong.com/courses博客:chenxiaosong.com/blog贡献:chenxiaosong.com/contributions邮箱:[email protected]交流群:544216206,点击查看群介绍点......
  • Linux内核文件系统-什么是文件系统
    建议点击这里查看个人主页上的最新原文作者:陈孝松主页:chenxiaosong.com哔哩哔哩:陈孝松课程:chenxiaosong.com/courses博客:chenxiaosong.com/blog贡献:chenxiaosong.com/contributions邮箱:[email protected]交流群:544216206,点击查看群介绍点......
  • 手把手教你用linux安装Gromacs(2024 GPU-CUDA)
    文章目录1.Gromacs介绍2.Gromacs安装一、基础软件1.gcc下载安装2.g++下载安装3.python4.Cmake二、显卡驱动和CUDA安装1.显卡驱动2.CUDA安装3.Gromacs-2024GPU-CUDA安装可能遇到的问题1.错误一原因:解决方法:2.错误二原因:解决方法:3.错误三4.错误四结束语1.G......
  • Linux添加环境变量(gpt生成,实测有用)
    在Linux中添加PATH环境变量,可以通过修改用户的.bashrc、.bash_profile或.profile文件,也可以临时修改当前会话的PATH变量。以下是添加永久性PATH变量的方法:打开你的用户目录下的.bashrc文件:nano~/.bashrc在文件的末尾添加新的PATH内容,例如添加/usr/local/bin:exportPATH=$PA......
  • Linux进程信号(二)
    前文简单介绍了Linux中的信号产生和信号捕捉的初步认识,这一篇文章我们将进一步了解Linux信号中的阻塞信号,并深入理解信号捕捉的具体过程。阻塞信号概念解释在介绍阻塞信号之前,我们需要了解一些信号相关的概念:实际执行信号的处理动作称为信号递达(Delivery)信号从产生带递达之......
  • Linux 7 主机名修改、查看
    使用hostname命令修改主机名,它修改是transient主机名,即临时生效的主机名。直接修改/etc/hostname文件,它瞬时生效,重启后也生效(因为内核会根据它初始化transient主机名)。使用nmtui命令在图形化界面修改主机名。它会直接修改/etc/hostname文件,因此也是瞬时生效+永久生效的。使......
  • linux运维之用户管理 堡垒机+普通用户sudo提权
    一、简介普通用户通过堡垒机登录linux服务器,不允许使用root用户登录堡垒机;普通用户登录后,限制普通用户使用一些命令,如禁止使用某些命令,仅允许使用部分命令等;普通用户不知道root密码,普通用户不能修改root密码;二、sudoers配置0.添加一个测试用户#添加用户useraddalibaby#设置密码......