linux 信号

1,信号的基本概念

        举例说明:如果CPU当前正在执行一个进程代码,比如键盘输入Ctrl + c,则进程的用户空间代码被暂停执行,CPU也从用户态切换到了内核态来处理硬件中断

        这个时候Ctrl +c 解释成了一个SIGINT信号,记在该进程的PCB中(也可以说发送了一个SIGINT信号给这个进程)

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

        注意:ctrl -c 产生的信号只能发给前台进程,一个命令后面加个&可以放在后台运行,这样shell不必等待进程结束就可以接受新命令,启动新进程

    shell可以同时运行一个前台进程和多个后台进程,只有前台进程才能接到想Ctrl -c 而产生的一个信号,也就是说该进程的用户空间代码执行到任何地方都有可能收到SIGINT信号而终止,所以信号对于进程的控制流程来说是异步的


    信号产生的方式:

    1,用户在终端按下某些键的时候,终端驱动程序会发送信号给前台进程,例如Ctrl -C产生SIGINT信号,Ctrl-\产生SIGOUT信号,

    2,硬件异常产生的信号,这些条件是硬件检测到,然后通知内核,向当前进程发送适当的信号

    3,一个进程调用kill(2)函数可以发送信号给另一个进程,可以用kill(1)命令发送信号给某个进程


        信号处理常见方式:

    1,忽略此信号

    2,执行这个信号的默认处理动作

    3,提供一个信号处理函数,要求内核在处理该信号时切换到用户态处理这个函数,这就是捕捉一个信号



产生信号:

    SIGINT的默认处理动作是终止进程,SIGQUIT的默认处理动作是终止进程并且Core Dump

    Core Dump是当一个进程要异常终止时,可以选择把进程的用户空间内存数据全部保存到磁盘上,文件名通常是core,这叫做Core Dump.


    

由软件条件产生信号 ————

SIGPIPE和SIGALRM信号都是由软件条件产生的信号。以alarm函数 和SIGALRM信号为例。

函数原型: unsigned int alarm(unsigned int seconds),在头文件unistd.h中。

作用机制:调用alarm函数可以设定⼀个闹钟,也就是告诉内核在seconds秒之后给当前进程发SIGALRM信号, 该信号的默认处理动作是终⽌当前进程。这个函数的返回值是0或者是以前设定的闹钟时间还余下的秒数。

举个栗子

某人要小睡一觉,设定闹钟为30分钟之后响,20分钟后被别人吵醒了,但还想多睡一会儿。于是重新设定闹钟为15分钟之后响,“以前设定的闹钟时间还余下的时间”就是10分钟。

如果seconds值为0,表示取消以前设定的闹钟,函数的返回值仍然是以前设定的闹钟时间还余下的秒数

闹钟:在一段时间之后才产生的信号(这个机制是不是和sleep函数有点像呢。。。)

代码:

linux 信号

执行结果:

linux 信号