• 信号(1.信号概念 2.信号的处理方式 3.信号阶段 用户态,内核态)


    1.临界资源

    被多个进程能够看到看到额资源叫做临界资源
    如果没有堆临界资源进任何的保护,对于临界资源的访问,双方访问都是乱序的,可能会因为读写交叉导致的各种乱码,废弃数据/访问控制方面的问题

    2.临界值

    对多个进程而言,访问临界资源的代码叫做临界区,比如二个访问共享内存的那一句代码

    3.原子性

    我们把一件事情,要么没做,要么做了,没有中间状态,我们叫做原子性

    4.互斥

    任何时刻,只允许一个进程,访问临界资源,这个我们叫做互斥

    5.什么是信号量

    信号量的本质是计数器
    比如你去电影院看电影,电影院可以给多个人访问,我们叫临界资源,电影院只有100个座位,代表了只能有100张票,,因为多了的话就会的座位发生冲突
    那么你怎么证明,放映厅里面特定的座位是你的,那么肯定是我买到了票,这个座位就是我的,那么买票的本质是对放映厅中特定的座位的一种,预定机制,那么你不去也没人坐,理想状态,人可能一样会坐,但是计算机里面的数据不会,那么怎么防止卖票卖多了,只要我们设定了一个值int count = 100,卖到了一张就count–,如果count为零就不卖,等有没有人退票或者电影看完下一场,买票的过程要保证原子性,比如一开始有个进程执行操作,操作到一半,发生进程切换换成另一个进程直接买50张票,买完50张票count-- 50次进程退出,回到最开始的那个进程,他又把count改回了100,那么这样就会因为进程交叉,而出现的数据错误,所以我们要保证原子性

    总结
    信号量是一个计时器,这个计时器对应的操作是原子的

    6.什么是信号

    1.信号概念

    比如红绿灯,闹钟等等,我们要先能识别信号的能力,比如绿灯行,红灯停,闹钟醒了就起床,所以我们要能识别信号所表达的意思,还有闹钟,我们设置闹钟的时候我们早就知道了信号产生之后要做什么,即便当前信号还没产生,也就是闹钟还没响,而这个是叫做提前知道信号的处理方法,而我们知道信号所表达的意思和提前知道信号的处理方法,具备了这二种我们就有了处理特定信号的能力

    那么我们把现实情况带入进程和信号
    信号是进程发送得,所以进程要具备处理信号的能力
    1.该能力一定是预先早就已经有了
    2.进程能够识别对应的信号
    3.进程能够处理对应的信号

    #include
    #include
    
    int main()
    {
       
        while(1)
        {
       
            sleep(1);
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    我们来运行下面代码
    在这里插入图片描述
    ctrl + c 把进程终止掉

    在这里插入图片描述

    ./myproc & //把当前进程添加到后台进程
    
    • 1

    在这里插入图片描述
    jobs查看后台进程

    在这里插入图片描述
    fg 1 查找后台任务,把1放在前台任务,我们在ctrl+c,那么他就没终止了

    在这里插入图片描述

    在这里插入图片描述
    如果你想要关闭后台进程,但是你后悔了那么就ctrl + z 这个时候我们调用jobs命令看到进程属于停止状态,我们bg 加进程号,他就恢复了运行状态了

    2.信号的处理方式

    因为信号产生时异步,当信号产生的时候,对应的进程可能正在做更重要的事情,我们进程可以暂时不处理这个信号,但是你必须要记住这个信号已经来了,等他完成了手上的事在来处理这个信号,
    而信号的处理分分三种处理方式
    1.默认动作 你送给你女朋友一个小礼物(处于热恋中),你女朋友表示很高兴
    2.忽略 你和你女朋友发生了冷战,那么你再送给他礼物,他忽略你
    3.自定义动作 和不同的人有不同的对应方式
    而上面这种叫做信号的处理,专业点叫信号的捕捉

    3.信号阶段

    1.信号使用前,信号的产生

    ctrl c ctrl z ctrl d 等等就是产生信号 ctrl + c就是向前台产生2信号
    kill -l看信号
    在这里插入图片描述
    那么我们怎么证明是发送2号信号
    在这里插入图片描述
    signum,给特定信号设置捕捉动作,第二个参数是函数指针,可以自定义动作的函数指针

    #include
    #include
    #include
    
    using namespace std;
    
    void handler(int signo)
    {
       
        cout<<"我是一个进程,刚刚获取了一个信号: "<< signo <<endl;
    }
    
    int main()
    {
       
        signal(SIGINT,handler);
    
        sleep(3);
    
        while(true)
        {
       
            cout<<"我是一个正在运行的进程 "<< getpid() <<endl;
            sleep(1);
        }
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    可以看到我输入了ctrl + c,他就发出了信号是二,这里要注意的是,handler这里只是设置了,是SIGINT出信号了,才调用handler函数,如果没有信号了,那么永远都不会使用handler函数
    在这里插入图片描述

    用户层产生信号的方式,键盘产生,操作系统给进程发送(写入)信号

    除了使用键盘发送信号,我们还能通过函数来发送信号

    通过kill函数来发送信号

    kill有二个参数,第一个是要发送的pid,第二个参数是发送的信号
    发送信号失败错误返回-1
    mykill.cc

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    using namespace std;
    
    
    static 
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • 相关阅读:
    java后端返回给前端不为空的属性
    Azure - 机器学习:自动化机器学习中计算机视觉任务的超参数
    python最优化算法实战---线性规划之内点法
    IgA | 对抗病原菌,帮助共生菌定植的“重要开关”
    java计算机毕业设计社交的健身网课平台服务器端源码+系统+数据库+lw文档+mybatis+运行部署
    Java核心知识:日期和时间总结 -- Date、DateFormat、Calendar
    1-12Vmware新增SSH功能
    HIS医疗项目
    搞懂SpringBean生命周期与依赖注入:你还在为这些热门技术感到困惑吗?Comate插件来帮你解答!
    解决wget下载过慢的问题
  • 原文地址:https://blog.csdn.net/li1829146612/article/details/127796711