分类: Python/Ruby
2011-12-05 15:07:08
转载文章请注明,转载自:扶凯[]
本文链接:
linux中的信号
先了解在linux中的信号,信号其实就是编程里俗称的中断,它使监视与控制其他进程变为有可能。中断信号(signal,又简称为信号)用来通知进程发生了异步事件。进程之间可以互相通过系统调用kill发送软中断信号。内核也可以因为内部事件而给进程发送信号,通知进程发生了某个事件。注意,信号只是用来通知某进程发生了什么事件,并不给该进程传递任何数据。
首先看看linux中的常用信号,见如下列表:
========================================================================
信号名 值 标注 解释
————————————————————————
HUP 1 A 检测到挂起
INT 2 A 来自键盘的中断
QUIT 3 A 来自键盘的停止
ILL 4 A 非法指令
ABRT 6 C 失败
FPE 8 C 浮点异常
KILL 9 AF 终端信号
USR1 10 A 用户定义的信号1
SEGV 11 C 非法内存访问
USR2 12 A 用户定义的信号2
PIPE 13 A 写往没有读取者的管道
ALRM 14 A 来自闹钟的定时器信号
TERM 15 A 终端信号
CHLD 17 B 子进程终止
CONT 18 E 如果被停止则继续
STOP 19 DF 停止进程
TSTP 20 D tty键入的停止命令
TTIN 21 D 对后台进程的tty输入
TTOU 22 D 对后台进程的tty输出
————————————————————————
著明:上表中‘值’列下没有列出的值所对应的信号为系统调用的非标准信号。上表中的第三列‘标注’定义了当进程接受到信号后的默认的操作
A—–终止进程
B—–忽略进程信号
C—–终止进程并卸下内核
D—–停止进程
E—–恢复进程
F—–不能截取或忽略进程信号
========================================================================
Perl中命令信号的原理
Perl 提供了%SIG 这个特殊的默认HASH.调用需要使用到系统保留全局HASH数组%SIG,即使用’$SIG{信号名}’截取信号,相当于,在perl程序中出现这个信号时,执行我们自己定义某段代码(子函数)的地址值(定义信号响应函数),这代码就是截取这个信息后要执行的结果了。
例如:
最程序运行前,我们给$SIG{TERM}和$SIG{INT}二个hash放一个子函数的引用(地址),当有终端信号或来自键盘的中断时,上面的while中的就不在运行,就开始运行yoursub这个函数.
可以使用的地方
象对信息的处理,我们常用到的地方,可以捕捉die及一些warning的信息,然后打印出来,我们也可以让程序在退出来之前,就是按下Ctrl+c时,进行一些任务(如删除tmp文件),需要注意的地方是.为了尽可能早的加载这些代码,这样就能保证程序一执行就能先得到信号。 这样用处非常大,比如我们写的perl的CGI.可以用信号来捕捉CGI程序Internal 500 错误,不然出现了问题,大多数都必须查看Web server的日志才能知道程序哪里出了错误,页面只一个500服务器错误,象php因为是mod,直接就显示在网页上。 可以使用如下的方法.比如将信号捕捉代码放到BEGIN块中
当然perl的CGI的500错误,用下面的模块CGI::Carp来处理会更加容易些
|
use CGI::Carp qw(fatalsToBrowser);
die 'Bad error here'; |
另一个常用的用法使用$SIG{ALRM},设置等待超时一般都这样做:
有时我们要杀死所有的子进行,需要用到向进程组发送信息
在perl中,进程组的ID就是$$.如果程序想给所有由它启动的所有子进程发送一个挂起的信号号,现实的方法,先调用setpgrp(0,0),使自己成为新的进程组的领头.这样不管是fork还是open,还是system都无所谓.
当然先排除自己
父进程将代码段,堆栈段,数据段完全复制一份给子进程。也就是说,在子进程运行之初,它拥有父进程的一切变量和句柄。例如,父进程申明了某个hash表,那这个hash表也会被子进程拥有。
然而,一旦子进程开始运行,它的数据段和堆栈段就在内存里完全和父进程分离开了。也就是说,两个进程间不再共享任何数据。例如前面所说的hash表,虽然子进程从父进程处继承了这个数据结构,但子进程写往hash里的数据,不会被父进程访问到。
Fork出来的僵死进程
如果进程退出时,会向父发送一个CHLD的信号后,就会变成僵死的进程,需要父进程使用wait和waitpid来收割.当然,也可以设置$SIG{CHLD}为IGNORG
在 Unix 系统上守护进程化
对于 Fork 出来的程序,我们常常需要给进程推到后台,不然在前台程序会一直占用,当关掉当前 shell 时,程序就退出了。如下有个 <