Linux信号的产生和处理

    xiaoxiao2021-04-14  87

    信号

         基本概念:信号机制是一种一步的通知机制,用来提醒进程一个事件已经发生。当一个信号发送给一个进程,操作系统中断了进程正常的控制流程,此时,任何非原子操作都将被中断。如果进程定义了信号的处理函数,那么它将被执行,否则就执行默认的处理函数。举个例子:

            ①用户输入命令,在shell下启动一个前台进程;

            ②用户键盘输入Ctrl+C产生一个硬件中断。如果当前CPU正在执行这个程序的代码,则代码暂停执行,CPU从用户态切到内核态来处理这个硬件中断;

            ③终端驱动程序将Ctrl+C解释成SIGINT信号,记录在该进程的PCB中;

            ④当某个时刻要从内核态返回该进程用户空间代码继续执行,首先要处理PCB中记录的信号,发现有一个SIGINT信号未处理,而这个信号的默认处理动作是终止进程,所以直接终止进程而不再返回它的用户空间代码执行。

         

         ◎简单分类:使用 kill -l 命令可以查看系统定义的信号列表:

            

            对这些信号做一个简单的分类:1~31这31个信号称为非实时信号,它们不支持排队,都不可靠;而34~64这31个信号是实时信号,支持排队,都是可靠信号。

     

     

    信号的产生

            产生信号的主要方式有:①通过终端按键产生信号;②调用系统函数向进程发信号;③由软件条件产生信号。

          通过终端按键产生信号:

            用户在终端按下某些键时,终端驱动程序会向前台进程发送信号。比如Ctrl+C产生SIGINT信号,Ctrl+\产生SIGQUIT信号,Ctrl+Z产生SIGTSTP信号等。

            其中,SIGTSTP信号的默认处理动作是终止进程并且Core Dump。Core Dump是指当一个进程异常终止时,可以选择把进程的用户空间内存数据全部保存到磁盘上,文件名通常为core。进程异常终止通常是因为由Bug,事后可以通过调试器检查core文件以查找错误原因,这叫做Post-mortem Debug(事后调试)。默认是不允许产生core文件的,但开发调试阶段可以用ulimit命令改变这个限制,允许产生core文件。

            ulimit -a (显示当前所有的资源限制):

                 

            ulimit -c 1024 (允许core文件最大为1024k):

                 

           在前台执行一个死循环程序,然后在终端键入Ctrl+\:

                 

            这时会生成一个core文件,接着就可以使用core文件了:

                 

            

         ◎调用系统函数向进程发信号:

            命令部分学过,利用kill命令可以发送信号给某个进程,而kill命令是调用kill函数实现的。当内核检测到某种软件条件发生时已可以通过信号通知进程,比如闹钟超时产生SIGALRM信号,向读端已关闭的管道写数据时产生SIGPIPE信号等。

            在后台执行死循环程序,用kill命令向它发送SIGSEGV信号:

                 

            kill命令是调用kill函数实现的。kill函数可以给一个指定的进程发送指定的信号。

            

            raise函数可以给当前进程发送指定信号(自己向自己发送信号)。

             

                

           运行结果:

                

     

         由软件条件产生信号:

           调用alarm函数可以设定一个闹钟,即告诉内核在seconds秒之后给当前进程发送SIGALRM信号,该信号的默认处理动作是终止当前进程。

           

             

            这个程序的作用是1秒之内一直累加,1秒之后被SIGALRM信号终止。

            运行结果:

              

     

    处理动作

          忽略此信号

          执行该信号的默认处理信号

          提供一个信号处理函数,要求内核在出炉该信号时切换到用户态执行这个处理函数,这种方式称为捕捉一个信号。

            signal函数

            

     

    转载请注明原文地址: https://ju.6miu.com/read-670521.html

    最新回复(0)