zoukankan      html  css  js  c++  java
  • 进程信号

    进程信号:
        信号概念:信号就是一个软件中断,通知进程发生了某件事情(打断当前阻塞操作,选择一个合适的时机去处理信号)
        
        功能:通知事件的发生
                
        能够识别信号
        
        信号有不同种类:
            查看种类:(共有62种)
                命令:kill -l
                
                1号—31号(非实时信号):linux继承unix的信号(非可靠信号,表示信号可能会丢失)
                    当有多个信号一起来的时候,只会处理一个信号
                
                34号—64号(实时信号):可靠信号,表示信号不会丢失
        
        信号有生命周期:
            
            信号的产生——>信号在进程中的注册——>信号在进程中的注销——>信号的处理(消亡)
                
            信号的产生:
                硬件: ctrl + c; ctrl + |; ctrl + z(中断一个前台进程)
                软件: kill命令; kill(); raise(); abort(); alarm();
                
                接口函数:
                    int kill(int pid, int sig)
                        给指定的 pid 发送指定的信号 sig
                    int raise(int sig)
                        给调用进程发送 sig 信号
                    void abort(void)
                        给调用进程发送 SIGABRT 信号
                    unsigned int alarm(unsigned int seconds)
                        seconds 秒后给调用进程发送一个 SIGALRM 信号
                        若 seconds = 0, 则取消上一个定时器
                        alarm(1);//表示取消上一个定时器,在设定 seconds = 1 的定时器
                        返回值: 若第一次使用 alarm 则返回 0; 若不是则返回上一个定时器剩余的时间
            
            信号在进程中的注册:修改未决信号集合对应位图,添加sigqueue结点
                sigset_t 信号集合(位图)
                pcb->struct sigpending->sigset_t signal
                未决信号:注册了但是没有被处理的信号
                未决:是一个信号从产生到信号处理之间所处的状态
                
                sigset_t结构体的认识:unsigned long int_val[_SIGSET_NWORDS];
                是一个128位的位图,用于对信号是否到来做标记
                
                sigqueue是一个链表,信号到来后会组织一个对应信号的节点,添加到链表中
                
                非可靠信号:判断如果位图已经标记,将什么都不做(每一个信号只添加一个节点,
                            信号同时到来时,有可能丢失事件)
                可靠信信号:不管位图是否标记,都会为每个到来的信号组织一个节点,添加到链表中,标记位图
        
                    可靠/非可靠信号:最大区别:是否位每个到来的信号添加isgqueue节点
                
            在进程中注销信号:删除信号的sigqueue节点,修改位图
                可靠信号的注销:删除结点,判断链表中是否还有相同节点,如果没有在位图置0,否则位图不变
                
                非可靠信号的注销:删除节点,修改位图位0
                
            信号的处理:
                1.默认处理方式
                    SIG_DFL
                2.忽略处理方式
                    SIG_IGN
                3.自定义处理方式
                    signal()
                    
                        typedef void (*sighandler_t)(int);
                        sighandler_t signal(int signum, sighandler_t handler);
                            signum:信号编号    handler:信号的处理方式
                
                    sigaction()
                        使用act 动作替换signum信号的处理方式,将原来的处理方式放到oldact中
                        
                        int sigaction(int signum, const struct sigaction* act, struct sigaction*oldact);
                            signum:信号编号        act:新的信号动作    oldact:保存旧的信号动作
                        
                        int sigemptyset(sigset_t *set);———>清空信号集合
                
                自定义处理信号的捕捉流程:        
                    什么时候才会处理信号的事件:
                        
                    main()经过系统调用/中断/异常来完成 “ 内核功能从内核态返回用户态的到时候”  判断是否有信号待处理,
                    如果有,并且这个信号处理方式是忽略/默认方式,则直接在内核态完成。
                    如果这个信号处理方式是自定义处理方式则返回一个sig_return,执行完毕后返回内核态,没有处理信号,则返回主控流程
                    
                进程从用户态运行切换到内核态运行:系统调用,中断,异常
            
                信号的阻塞:阻止信号被递达
                    递达:一个动作——表示信号处理
                    阻止信号表示在进程pcb 的 block 信号集合中标记信号并且暂时不处理,不代表信号不会被传递,
                    直到被解除阻塞(从 block 集合中解除)
                    
                    信号集合 sigset_t -> long int_val[16],使用位图作为信号的位图    
                        
                    对信号阻塞集合进行操作的接口:
                        int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
                        
                            how:
                                SIG_BLOK    blocked = blocked | set  //添加
                                SIG_UNBLOCK    blocked = blocked & ~set //移除
                                SIG_SETMASK    blocked = set              //直接设置
                            set: 要阻塞/解除阻塞的信号集合
                            oldset:被用于保存修改前,blocked集合原有数据
                
                        int sigemptyset(sigset_t *set);———>清空信号集合
                    
                        int sigfillset(sigset_t *set);———>将所有信号添加到set的集合中
                        
                        int sigaddset(sigset_t *set, int signum);———>将指定信号,添加到指定集合中
                        
                        int sigpending(sigset_t *set);———>获取未决信号集合
                        
                        int sigismember(const sigset_t *set, int signum);———>判断是否在信号集合中
                
                        int sigdelset(sigset_t *set, int signum);———>从集合中删除信号
                
                哪些信号是不能被阻塞的:
                    带有unblockable表示不能被阻塞
                    所有信号中:SIGKILL(强杀), SIGSTOP()信号无法被阻塞,无法被自定义处理,无法被忽略。
                    可靠信号不会丢失,非可靠信号可能会丢失
                
        竞态条件:程序运行时序的竞争执行(体会竞态条件/理解函数的可重入与不可重入)
            
            函数的可重入/不可重入:
                一个函数在不同的执行流下是否可以被重复调用,并且不会出现问题,有可能出问题,这个函数
                就是不可重入函数;否则是可重入函数
        
            原子操作:操作不可被打断
            
            函数的可重入/不可重入的关键点在:
                是否对全局数据进行了非原子操作
                
            当用户自己设计接口时,如果有可能在多个执行流中被调用,那么就要考虑函数中对全局数据操作的保护
            在多个执行流中调用相同的函数,也要考虑这个函数是否可能重入
            比如:malloc/free
     
            关键字:volatile 用于修饰一个变量——保持变量内存可见性
                每次对变量进行操作都要从内存中重新获取数据
                功能:防止编译器过度优化代码
                -O2
                C语言中常用的关键字:
                    变量类型关键字(解释内存中数据的特性):
                        static ->1.正对变量(作用域,证明周期),2.正对函数
                        const->
                        volatile->
            
            SIGCHILD信号:
                子进程退出时操作系统给父进程发送的信号。(默认处理方式是忽略,导致父进程没有处理子进程的退出,导致僵尸进程)
                避免僵尸进程:
                    1.死等: wait waitpid
                    2.修改信号处理方式:在信号的回调函数中调用wait/waitpid 处理子进程推出事件
                
                因为SIGCHILD 信号是一个非可靠信号,在大量子进程同时退出的情况下,可能会丢失信号,因此在一次回调时,
                把能处理的僵尸子进程全部处理。
                    sigcb()
  • 相关阅读:
    十七:CSS之CSS继承和层叠
    十六:CSS之CSS选择器之后代选择器、伪类选择器
    十五:CSS之CSS选择器之群组选择器、全局选择器
    十四:CSS之CSS选择器之标签选择器、类选择器、ID选择器
    Android开发技巧——ViewPager加View情况封装PagerAdapter的实现类
    JAVA知识笔记
    机器学习笔记
    设计模式学习
    Android小知识汇总
    判断GPS是否开启&转到设置GPS界面
  • 原文地址:https://www.cnblogs.com/cuckoo-/p/11409952.html
Copyright © 2011-2022 走看看