signal的运用第一:给耗时操作增加统一的TimeOut超时处理机制无论是否启用了Python的多线程机制,只要利用signal模块就可以为耗时操作增加统一的超时处理机制(当然在使用了多线程的情况下还是有一些不一样的地方,只有在主线程里面才可以调用signal.signal函数,而子线程可以调用signal.alarm函数对信号的状态进行设置,具体需参照signal模块自身文档)。单线程情况下,可直接参考如下示例:Code:importsignaldefhandler(signum,frame):print'Signalhandlercalledwithsignal',signumraiseTimeOutError,TimeOut!try:#Setthesignalhandleranda1-secondalarmsignal.signal(signal.SIGALRM,handler)signal.alarm(1)#ThiswhileloophangindefinitelywhileTrue:print'a',signal.alarm(0)#Disablethealarmexcept:printprint'Timeoutcaught!'第二:pythonkill信号处理(优雅关闭服务器)我们可能使用nohup或者自己写一个在后台运行的daemon,然后关闭的时候使用kill命令。但是我们有时候需要在关闭服务器之前做一些事情,比如回收一些资源,关闭数据库连接池等,要实现优雅的关闭服务器,就需要对kill的信号进行处理,python的信号处理用到signal模块。看下面的例子:Code:importsignalimporttimeimportsysimportthreading#想捕捉的信号编号signum=int(sys.argv[1])classThreadTest(threading.Thread):def__init__(self):threading.Thread.__init__(self)defrun(self):whileTrue:printiamoktime.sleep(1)defmyhandle(signum=0,e=0):处理信号的函数print'iwillkillmyself'print'receivesignal:%dat%s'%(signum,str(time.ctime(time.time())))sys.exit()if__name__==__main__:signal.signal(signum,myhandle)tt=ThreadTest()tt.start()whileTrue:time.sleep(1)上面的例子接受一个参数,是要捕捉的信号,里面是模拟一个多线程的服务器。下面用nohup启动:nohuppythonsignal_test.py15&我们监听的是15,也就是kill进程号默认的值,然后打开看日志:tail-fnohup.out接着3秒后关闭服务器:kill91943日志里面就会打印出记录:iamokiamokiamokiwillkillmyselfreceivesignal:15atThuAug517:25:352010注意kill-9进程号程序是不能处理9这个的,9是强制关闭程序。除了15之外,如果15被系统用了,你也可以选择其他的使用。可以通过kill-l来列出所有的信号,如下:Code:$kill-l1)SIGHUP2)SIGINT3)SIGQUIT4)SIGILL5)SIGTRAP6)SIGABRT7)SIGEMT8)SIGFPE9)SIGKILL10)SIGBUS11)SIGSEGV12)SIGSYS13)SIGPIPE14)SIGALRM15)SIGTERM16)SIGURG17)SIGSTOP18)SIGTSTP19)SIGCONT20)SIGCHLD21)SIGTTIN22)SIGTTOU23)SIGIO24)SIGXCPU25)SIGXFSZ26)SIGVTALRM27)SIGPROF28)SIGWINCH29)SIGINFO30)SIGUSR131)SIGUSR2sys.exit()是会清理才退出的,在某些多线程情况下如果不行的话就使用os.abort(),这个是强制退出。from:=179补充:POSIX.1中列出的信号:信号值处理动作发出信号的原因----------------------------------------------------------------------SIGHUP1A终端挂起或者控制进程终止SIGINT2A键盘中断(如break键被按下)SIGQUIT3C键盘的退出键被按下SIGILL4C非法指令SIGABRT6C由abort(3)发出的退出指令SIGFPE8C浮点异常SIGKILL9AEFKill信号SIGSEGV11C无效的内存引用SIGPIPE13A管道破裂:写一个没有读端口的管道SIGALRM14A由alarm(2)发出的信号SIGTERM15A终止信号SIGUSR130,10,16A用户自定义信号1SIGUSR231,12,17A用户自定义信号2SIGCHLD20,17,18B子进程结束信号SIGCONT19,18,25进程继续(曾被停止的进程)SIGSTOP17,19,23DEF终止进程SIGTSTP18,20,24D控制终端(tty)上按下停止键SIGTTIN21,21,26D后台进程企图从控制终端读SIGTTOU22,22,27D后台进程企图从控制终端写处理动作一项中的字母含义如下:A缺省的动作是终止进程B缺省的动作是忽略此信号C缺省的动作是终止进程并进行内核映像转储(dumpcore)D缺省的动作是停止进程E信号不能被捕获F信号不能被忽略键盘和shell的交互:Ctrl-cKillforegroundprocess常用;送SIGINT信号,默认进程会结束,但是进程自己可以重定义收到这个信号的行为。Ctrl-zSuspendforegroundprocess;送SIGSTOP信号,进程只是被停止,再送SIGCONT信号,进程继续运行。Ctrl-dTerminateinput,orexitshell常用有时也会使程序退出,例如没有参数的cat命令,从终端读一行显示一行,知道Ctrl+D终结输入并终结进程;不是发送信号,而是表示一个特殊的二进制值,表示EOF。Ctrl-sSuspendoutputCtrl-qResumeoutputCtrl-oDiscardoutputCtrl-lClearscreen控制字符都是可以用(stty命令)更改的。可以用stty-a看看终端配置。有些信号不能被屏蔽,比如中断,还应该有杀死进程的信号,要不然内核怎么做操作系统中的老大。实际上,SIGKILL和SIGSTOP信号是不能被屏蔽或阻止的,他们的默认动作总是会被执行的python多线程程序的中断(信号)处理下的信号