Python标准库07 信号 (signal包,部分os包)
作者:Vamei 出處:http://www.cnblogs.com/vamei 歡迎轉(zhuǎn)載,也請(qǐng)保留這段聲明。謝謝!
?
在了解了Linux的信號(hào)基礎(chǔ)之后,Python標(biāo)準(zhǔn)庫中的signal包就很容易學(xué)習(xí)和理解。signal包負(fù)責(zé)在Python程序內(nèi)部處理信號(hào),典型的操作包括預(yù)設(shè)信號(hào)處理函數(shù),暫停并等待信號(hào),以及定時(shí)發(fā)出SIGALRM等。要注意,signal包主要是針對(duì)UNIX平臺(tái)(比如Linux, MAC OS),而Windows內(nèi)核中由于對(duì)信號(hào)機(jī)制的支持不充分,所以在Windows上的Python不能發(fā)揮信號(hào)系統(tǒng)的功能。
?
定義信號(hào)名
signal包定義了各個(gè)信號(hào)名及其對(duì)應(yīng)的整數(shù),比如
import signal print signal.SIGALRM print signal.SIGCONTPython所用的信號(hào)名和Linux一致。你可以通過
$man 7 signal
查詢
?
預(yù)設(shè)信號(hào)處理函數(shù)
signal包的核心是使用signal.signal()函數(shù)來預(yù)設(shè)(register)信號(hào)處理函數(shù),如下所示:
singnal.signal(signalnum, handler)
signalnum為某個(gè)信號(hào),handler為該信號(hào)的處理函數(shù)。我們在信號(hào)基礎(chǔ)里提到,進(jìn)程可以無視信號(hào),可以采取默認(rèn)操作,還可以自定義操作。當(dāng)handler為signal.SIG_IGN時(shí),信號(hào)被無視(ignore)。當(dāng)handler為singal.SIG_DFL,進(jìn)程采取默認(rèn)操作(default)。當(dāng)handler為一個(gè)函數(shù)名時(shí),進(jìn)程采取函數(shù)中定義的操作。
import signal # Define signal handler function def myHandler(signum, frame):print('I received: ', signum)# register signal.SIGTSTP's handler signal.signal(signal.SIGTSTP, myHandler) signal.pause()print('End of Signal Demo')
?
在主程序中,我們首先使用signal.signal()函數(shù)來預(yù)設(shè)信號(hào)處理函數(shù)。然后我們執(zhí)行signal.pause()來讓該進(jìn)程暫停以等待信號(hào),以等待信號(hào)。當(dāng)信號(hào)SIGUSR1被傳遞給該進(jìn)程時(shí),進(jìn)程從暫停中恢復(fù),并根據(jù)預(yù)設(shè),執(zhí)行SIGTSTP的信號(hào)處理函數(shù)myHandler()。myHandler的兩個(gè)參數(shù)一個(gè)用來識(shí)別信號(hào)(signum),另一個(gè)用來獲得信號(hào)發(fā)生時(shí),進(jìn)程棧的狀況(stack frame)。這兩個(gè)參數(shù)都是由signal.singnal()函數(shù)來傳遞的。
上面的程序可以保存在一個(gè)文件中(比如test.py)。我們使用如下方法運(yùn)行:
$python test.py
以便讓進(jìn)程運(yùn)行。當(dāng)程序運(yùn)行到signal.pause()的時(shí)候,進(jìn)程暫停并等待信號(hào)。此時(shí),通過按下CTRL+Z向該進(jìn)程發(fā)送SIGTSTP信號(hào)。我們可以看到,進(jìn)程執(zhí)行了myHandle()函數(shù), 隨后返回主程序,繼續(xù)執(zhí)行。(當(dāng)然,也可以用$ps查詢process ID, 再使用$kill來發(fā)出信號(hào)。)
(進(jìn)程并不一定要使用signal.pause()暫停以等待信號(hào),它也可以在進(jìn)行工作中接受信號(hào),比如將上面的signal.pause()改為一個(gè)需要長時(shí)間工作的循環(huán)。)
?
我們可以根據(jù)自己的需要更改myHandler()中的操作,以針對(duì)不同的信號(hào)實(shí)現(xiàn)個(gè)性化的處理。
?
定時(shí)發(fā)出SIGALRM信號(hào)
一個(gè)有用的函數(shù)是signal.alarm(),它被用于在一定時(shí)間之后,向進(jìn)程自身發(fā)送SIGALRM信號(hào):
import signal # Define signal handler function def myHandler(signum, frame):print("Now, it's the time") exit()# register signal.SIGALRM's handler signal.signal(signal.SIGALRM, myHandler) signal.alarm(5) while True:print('not yet')我們這里用了一個(gè)無限循環(huán)以便讓進(jìn)程持續(xù)運(yùn)行。在signal.alarm()執(zhí)行5秒之后,進(jìn)程將向自己發(fā)出SIGALRM信號(hào),隨后,信號(hào)處理函數(shù)myHandler開始執(zhí)行。
?
發(fā)送信號(hào)
signal包的核心是設(shè)置信號(hào)處理函數(shù)。除了signal.alarm()向自身發(fā)送信號(hào)之外,并沒有其他發(fā)送信號(hào)的功能。但在os包中,有類似于linux的kill命令的函數(shù),分別為
os.kill(pid, sid)
os.killpg(pgid, sid)
分別向進(jìn)程和進(jìn)程組(見Linux進(jìn)程關(guān)系)發(fā)送信號(hào)。sid為信號(hào)所對(duì)應(yīng)的整數(shù)或者singal.SIG*。
?
實(shí)際上signal, pause,kill和alarm都是Linux應(yīng)用編程中常見的C庫函數(shù),在這里,我們只不過是用Python語言來實(shí)現(xiàn)了一下。實(shí)際上,Python 的解釋器是使用C語言來編寫的,所以有此相似性也并不意外。此外,在Python 3.4中,signal包被增強(qiáng),信號(hào)阻塞等功能被加入到該包中。我們暫時(shí)不深入到該包中。
?
總結(jié)
signal.SIG*
signal.signal()
signal.pause()
signal.alarm()
轉(zhuǎn)載于:https://www.cnblogs.com/vamei/archive/2012/10/06/2712683.html
總結(jié)
以上是生活随笔為你收集整理的Python标准库07 信号 (signal包,部分os包)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ios 跳转到某 app 的评价区域、由
- 下一篇: JAVA大数的运用