Linux以进程为单位来执行程序。咱们能够将计算机看做一个大楼,内核(kernel)是大楼的管理员,进程是大楼的房客。每一个进程拥有一个独立的房间(属于进程的内存空间),而每一个房间都是不容许该进程以外的人进入。这样,每一个进程都只专一于本身干的事情,而不考虑其余进程,同时也不让别的进程看到本身的房间内部。这对于每一个进程来讲是一种保护机制。(想像一下几百个进程老是要干涉对方,那会有多么混乱,或者几百个进程相互偷窥……) shell
然而,在一些状况,咱们须要打破封闭的房间,以便和进程交流信息。好比说,内核发现有一个进程在砸墙(硬件错误),须要让进程意识到这样继续下去会毁了整个大楼。再好比说,咱们想让多个进程之间合做。这样,咱们就须要必定的通讯方式。信号(signal)就是一种向进程传递信息的方式。咱们能够将信号想象成大楼的管理员往房间的信箱里塞小纸条。随后进程取出小纸条,会根据纸条上的内容来采起必定的行动,好比灯坏了,提醒进程使用手电。(固然,也能够彻底无视这张纸条,然而在失火这样紧急的情况下,无视信号不是个好的选择)。相对于其余的进程间通讯方式(interprocess communication, 好比说pipe, shared memory)来讲,信号所能传递的信息比较粗糙,只是一个整数。但正是因为传递的信息量少,信号也便于管理和使用。信号所以被常常地用于系统管理相关的任务,好比通知进程终结、停止或者恢复等等。 编程
信号是由内核(kernel)管理的。信号的产生方式多种多样,它能够是内核自身产生的,好比出现硬件错误(好比出现分母为0的除法运算,或者出现segmentation fault),内核须要通知某一进程;也能够是其它进程产生的,发送给内核,再由内核传递给目标进程。内核中针对每个进程都有一个表存储相关信息(房间的信箱)。当内核须要将信号传递给某个进程时,就在该进程相对应的表中的适当位置写入信号(塞入纸条),这样,就生成(generate)了信号。当该进程执行系统调用时,在系统调用完成后退出内核时,都会顺便查看信箱里的信息。若是有信号,进程会执行对应该信号的操做(signal action, 也叫作信号处理signal disposition),此时叫作执行(deliver)信号。从信号的生成到信号的传递的时间,信号处于等待(pending)状态(纸条尚未被查看)。咱们一样能够设计程序,让其生成的进程阻塞(block)某些信号,也就是让这些信号始终处于等待的状态,直到进程取消阻塞(unblock)或者无视信号。 函数
信号所传递的每个整数都被赋予了特殊的意义,并有一个信号名对应该整数。常见的信号有SIGINT, SIGQUIT, SIGCONT, SIGTSTP, SIGALRM等。这些都是信号的名字。你能够经过 spa
$man 7 signal
上面几个信号中, 设计
SIGINT 当键盘按下CTRL+C从shell中发出信号,信号被传递给shell中前台运行的进程,对应该信号的默认操做是中断 (INTERRUPT) 该进程。 code
SIGQUIT 当键盘按下CTRL+\从shell中发出信号,信号被传递给shell中前台运行的进程,对应该信号的默认操做是退出 (QUIT) 该进程。 进程
SIGTSTP 当键盘按下CTRL+Z从shell中发出信号,信号被传递给shell中前台运行的进程,对应该信号的默认操做是暂停 (STOP) 该进程。 ip
SIGCONT 用于通知暂停的进程继续。 内存
SIGALRM 起到定时器的做用,一般是程序在必定的时间以后才生成该信号。 it
下面咱们实际应用一下信号。咱们在shell中运行ping:
$ping localhost
[1]+ Stopped ping localhost
咱们能够在shell中经过$kill命令来向某个进程发出信号:
$kill -SIGCONT 27397
来传递SIGCONT信号给ping进程。在上面的例子中,全部的信号都采起了对应信号的默认操做。但这并不绝对。当进程决定执行信号的时候,有下面几种可能:
1) 无视(ignore)信号,信号被清除,进程自己不采起任何特殊的操做
2) 默认(default)操做。每一个信号对应有必定的默认操做。好比上面SIGCONT用于继续进程。
3) 自定义操做。也叫作获取 (catch) 信号。执行进程中预设的对应于该信号的操做。
进程会采起哪一种操做,要根据该进程的程序设计。特别是获取信号的状况,程序每每会设置一些比较长而复杂的操做(一般将这些操做放到一个函数中)。
信号经常被用于系统管理,因此它的内容至关庞杂。深刻了解信号,须要必定的Linux环境编程知识。
信号机制; generate, deliver, pending, blocking
signal action/dispositon; ignore, default action, catch signal
$kill