linux python 信号,Python模块之信号(signal)
在了解了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)-- 進(jìn)程之間通訊的方式,是一種軟件中斷。一個(gè)進(jìn)程一旦接收到信號(hào)就會(huì)打斷原來的程序執(zhí)行流程來處理信號(hào)。
定義信號(hào)名
signal包定義了各個(gè)信號(hào)名及其對(duì)應(yīng)的整數(shù),比如:import?signal
print(signal.SIGABRT)
print(signal.SIG_DFL)
Python所用的信號(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ù)。我們?cè)谛盘?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ù)中定義的操作。參數(shù)SIG_IGNSIG_DFLhandler解釋忽略默認(rèn)處理類型的函數(shù)指針
實(shí)質(zhì)#define SIG_IGN ((sighandler_t)1)#define SIG_IGN ((sighandler_t)0)執(zhí)行自己寫的代碼#?Define?signal?handler?function
def?myHandler(signum,?frame):
print('I?received:?',?signum)
#?register?signal.SIGTSTP's?handler
signal.signal(signal.SIGTSTP,?myHandler)
#暫停進(jìn)程,把當(dāng)前進(jìn)程置成就緒態(tài),讓出CPU,直到收到任意一個(gè)信號(hào)后終止,并且當(dāng)處理完該信號(hào)之后,直接執(zhí)行pause()函數(shù)下面的語句
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.pause阻塞函數(shù),讓進(jìn)程暫停以等待信號(hào),也就時(shí)阻塞進(jìn)程執(zhí)行,簡單來說當(dāng)接收到信號(hào)后使進(jìn)程停止。
signal.alarm()??常用作定時(shí)器,time為時(shí)間參數(shù),單位為秒
SIGINT 表示終止進(jìn)程
SIGQUIT 表示退出進(jìn)程
SIGSTP 表示暫停進(jìn)程
SIGKILL 表示結(jié)束某個(gè)進(jìn)程,不能被忽略處理。
SIGALRM 表示時(shí)鐘信號(hào),常用作定時(shí)器,time為時(shí)間參數(shù),單位為秒。
SIGSTOP表示停止某個(gè)進(jìn)程,且不能被忽略處理。
SIGCHLD表示子進(jìn)程發(fā)送給父進(jìn)程信號(hào)
SIGCONT 繼續(xù)執(zhí)行暫停的進(jìn)程
SIGINT? ? ?終止進(jìn)程? ? ?中斷進(jìn)程,不可通過signal.signal()捕捉(相當(dāng)于Ctrl+C)
SIGTERM? ? 終止進(jìn)程? ? ?軟件終止信號(hào),可通過signal.signal()捕捉(默認(rèn)信號(hào),當(dāng)os.kill()沒有指明信號(hào)類型時(shí),默認(rèn)的是該信號(hào))
SIGKILL? ? 終止進(jìn)程? ? ?殺死進(jìn)程,不可捕捉(相當(dāng)于linux下的kill命令,windows下使用會(huì)拋出異常)
SIGALRM? ? 鬧鐘信號(hào)? ? ?可以通過signal.alarm()和os.kill()發(fā)送該信號(hào),可通過signal.signal()捕捉
windows下只能使用這幾個(gè)信號(hào):SIGABRT
SIGFPE
SIGILL
SIGINT
SIGSEGV
SIGTERM
總結(jié)
以上是生活随笔為你收集整理的linux python 信号,Python模块之信号(signal)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: unity怎么制作云飘动_Unity 如
- 下一篇: isfull mysql_MySQL数据