Linux信号的产生和处理

信号

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

        ①用户输入命令,在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函数

        

猜你喜欢

转载自blog.csdn.net/wxt_hillwill/article/details/70162909
今日推荐