前面说的进程间通信,都是常规状态下的工作模式。对于异常情况下的工作模式,就需要用信号的方式来通知进程。
信号跟信号量两者用途完全不一样。
在Linux操作系统中,为了响应各种各样的事件,提供了几十种信号,分别代表着不同的意义。我们可以通过kill -1命令,查看所有的信号。
$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
运行在shell终端的进程,我们可以通过键盘输入某些组合键的时候,给进程发送信号。例如:
CTRL+C:产生SIGINT信号,表示终止该进程。
CTRL+Z:产生SIGTSTP信号,表示停止该进程,但还未结束。
如果进程在后台运行,可以通过kill命令的方式给进程发送信号,但前提需要知道运行中的进程PID号,例如:
kill -9 1050,表示给PID为1050的进程发送SIGKILL信号,用来立即结束该进程。
所以,信号事件的来源主要有硬件来源(例如键盘CTRL+C)和软件来源(如kill命令)。
信号是进程间通信机制中的唯一的异步通信机制,因为可以在任何时候发送信号给某一进程,一旦有信号产生,我们就有下面这几种,用户进程对信号的处理方式。
1、执行默认操作。Linux对每种信号都规定了默认操作,例如上面列表中的SIGTERM信号,就是终止进程的意思。但大部分信号的默认操作都可以通过回调函数的形式进行修改。
2、捕捉信号。我们可以为信号定义一个信号处理函数。当信号发生时,我们就执行相应的信号处理函数。
3、忽略信号。当我们不希望处理某些信号的时候,就可以忽略该信号,不做任何处理。有两个信号是应用进程无法捕捉和忽略的,即SIGKILL和SEGSTOP,它们用于在任何时候中断或结束某一进程。