tylderen +

Linux系列: signal

信号是进程间通信(ICP)的一种方式。简单而又强大。

信号的产生

信号是由内核管理的。 一般来说,信号的产生主要有三个原因:

  • 程序运行出错
  • 外部事件产生的信号
  • 主动产生信号

错误,意味着程序将要做某个不可以做的事情,不能继续进行下去了。比如 除0操作,以及非法的地址访问;但是绝大多数错误是不会有信号产生的。比如,打开一个不存在的文件时,会发生错误,但是不会产生信号,只是open会返回-1而已。

外部事件产生的信号一般是指,I/O有数据到达,或者是定时器到期,都会使用信号通知进程。还有就是子进程的终止也会向父进程发送信号(当子进程退出的时候,内核会向父进程发送SIGCHLD信号)

主动产生信号意味着调用像kill等函数主动产生一个信号。

信号的处理

  • 执行缺省操作
  • 忽略信号
  • 自己编写handler函数处理

执行缺省操作,Linux对每种信号都规定了默认操作。注意,进程对实时信号的缺省反应是进程终止。

忽略信号,即对信号不做任何处理,其中,有两个信号不能忽略:SIGKILLSIGSTOP

捕捉信号。定义信号处理函数,当信号发生时,执行相应的处理函数。

这时候可以想一下僵尸进程的产生过程:

当子进程完成自己的生命周期后,内核释放该进程所有的资源,包括打开的文件,占用的内存等。 但是会为其保留一些信息(包括进程号,退出码,退出状态,运行时间等),这些数据会一直保留到 系统将它传递给它的父进程为止,直到父进程通过调用wait / waitpid来释放。

防止产生僵尸进程

如果父进程不关心子进程什么时候结束,那就可以用signal(SIGCLD, SIG_IGN)signal(SIGCHLD, SIG_IGN) 通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收,并不再给父进程发送信号。这样, 僵尸进程就会被回收。

当然也还有其他防止产生僵尸进程的做法,我们这里不再展开了。

多线程信号处理的问题:

这个暂时还没有遇到过,但是许多人都在讲多线程处理信号需要特别的注意,留坑,会专门找个时间学习一下。

###代码 使用Python实现的signal小例子

Blog

Opinion

Project