本文关键字:
linux 管道通信,linux 进程通信方式,信号
信号是在软件层次上对中断机制的一种模拟。在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。信号可以直接进行用户空间进程和内核进程之间的交互,内核进程也可以利用它来通知用户空间进程发生了哪些系统事件。它可以在任何时候发给某一进程,而无须知道该进程的状态。如果该进程当前并未处于执行态,则该信号就由内核保存起来,直到该进程恢复执行再传递给它为止;如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞被取消时才被传递给进程。
信号是进程间通信机制中唯一的异步通信机制,可以看做是异步通知,通知接收信号的进程有哪些事情发生了。信号机制经过Posix实时扩展后,功能更加强大,除了基本通知功能外,还可以传递附加信息。
信号事件的发生有两个来源:硬件来源(如我们按下了键盘上的按钮或者出现其他硬件故障);软件来源,最常用发送信号的系统函数有kill()、raise()、alarm()、setitimer()和sigqueue()等,软件来源还包括一些非法运算等操作。
进程可以通过3种方式来响应一个信号。
1.忽略信号
忽略信号即对信号不做任何处理,其中,有两个信号不能忽略:SIGKILL和SIGSTOP。
2.捕捉信号
定义信号处理函数,当信号发生时,执行相应的处理函数。
3.执行默认操作
Linux对每种信号都规定了默认操作,如表1所示。
表1 常见信号的含义及其默认操作
信 号 名 | 含 义 | 默 认 操 作 |
SIGHUP | 该信号在用户终端连接(正常或非正常)结束时发出,通常是在终端的控制进程结束时,通知同一会话内的各个进程与控制终端不再关联 | 终止 |
SIGINT | 该信号在用户输入INTR字符(通常是Ctrl+C)时发出,终端驱动程序发送此信号并送到前台进程中的每一个进程 | 终止 |
SIGQUIT | 该信号和SIGINT类似,但由QUIT字符(通常是Ctrl+\)来控制 | 终止 |
SIGILL | 该信号在一个进程企图执行一条非法指令时(可执行文件本身出现错误,或者试图执行数据段、堆栈溢出时)发出 | 终止 |
SIGFPE | 该信号在发生致命的算术运算错误时发出。这里不仅包括浮点运算错误,还包括溢出及除数为0等其他所有的算术错误 | 终止 |
SIGKILL | 该信号用来立即结束程序的运行,并且不能被阻塞、处理和忽略 | 终止 |
SIGALRM | 该信号当一个定时器到时的时候发出 | 终止 |
SIGSTOP | 该信号用于暂停一个进程,且不能被阻塞、处理或忽略 | 暂停进程 |
SIGTSTP | 该信号用于交互停止进程,用户在输入SUSP字符时(通常是Ctrl+Z)发出这个信号 | 停止进程 |
SIGCHLD | 子进程改变状态时,父进程会收到这个信号 | 忽略 |
一个完整的信号生命周期可以分为3个重要阶段,这3个阶段由4个重要事件来刻画的:信号产生、信号在进程中注册、信号在进程中注销、执行信号处理函数。这里信号的产生、注册、注销等是指信号的内部实现机制,而不是信号的函数实现。因此,信号注册与否与本节后面讲到的发送信号函数(如kill()等)及信号安装函数(如signal()等)无关,只与信号值有关。
相邻两个事件的时间间隔构成信号生命周期的一个阶段。要注意这里的信号处理有多种方式,一般是由内核完成的,当然也可以由用户进程来完成,故在此没有明确指出。
信号的处理包括信号的发送、捕获及信号的处理,它们有各自相对应的常见函数。
● 发送信号的函数:kill()、raise()。
● 捕捉信号的函数:alarm()、pause()。
● 处理信号的函数:signal()、sigaction()。
本文选自华清远见
嵌入式培训教材
《从实践中学嵌入式Linux应用程序开发》