python中對信號的處理詳解
什么是信號
信號(signal)-- 進(jìn)程間通訊的一種方式,也可作為一種軟件中斷的方法。一個進(jìn)程一旦接收到信號就會打斷原來的程序執(zhí)行來按照信號進(jìn)行處理。
簡化術(shù)語,信號是一個事件,用于中斷運行功能的執(zhí)行。信號始終在主Python線程中執(zhí)行。對于信號,這里不做詳細(xì)介紹。
Python封裝了操作系統(tǒng)的信號功能的庫 singal 的庫。singal 庫可以使我們在python程序中中實現(xiàn)信號機制。
Python的信號處理
首先需要了解Python為什么要提供 signal Library。信號庫使我們能夠使用信號處理程序,以便當(dāng)接收信號時都可以執(zhí)行自定義任務(wù)。
Mission:當(dāng)接收到信號時執(zhí)行信號處理方法
可以通過使用 signal.singal() 函數(shù)來實現(xiàn)此功能
Python對信號的處理
通常情況下Python 信號處理程序總是會在主 Python 主解析器的主線程中執(zhí)行,即使信號是在另一個線程中接收的。 這意味著信號不能被用作線程間通信的手段。 你可以改用 threading 模塊中的同步原語。
Python信號處理流程,需要對信號處理程序(signal handling )簡要說明。signal handling 是一個任務(wù)或程序,當(dāng)檢測到特定信號時,處理函數(shù)需要兩個參數(shù),即信號id signal number (Linux 中 1-64),與堆棧幀 frame。通過相應(yīng)信號啟動對應(yīng) signal handling ,signal.signal() 將為信號分配 處理函數(shù)。
如:當(dāng)運行一個腳本時,取消,此時是捕獲到一個信號,可以通過捕獲信號方式對程序進(jìn)行異步的優(yōu)雅處理。通過將信號處理程序注冊到應(yīng)用程序中:
import signal import time def handler(a, b): # 定義一個signal handling print("Signal Number:", a, " Frame: ", b) signal.signal(signal.SIGINT, handler) # 將handle分配給對應(yīng)信號 while True: print("Press ctrl + c") time.sleep(10)
如果不對對應(yīng)信號進(jìn)行捕獲處理時,python將會拋出異常。
root@Seal:/mnt/d/pywork/signal# python signal.py ^CTraceback (most recent call last): File "signal.py", line 3, in <module> while True: KeyboardInterrupt
信號枚舉
信號的表現(xiàn)為一個int,Python的信號庫有對應(yīng)的信號枚舉成員
其中常用的一般有,
SIGINT control+c
SIGTERM 終止進(jìn)程 軟件終止信號
SIGKILL 終止進(jìn)程 殺死進(jìn)程
SIGALRM 超時
信號 | 說明 |
---|---|
SIG_DFL | |
SIG_IGN | 標(biāo)準(zhǔn)信號處理程序,它將簡單地忽略給定的信號 |
SIGABRT SIGIOT | 來自 abort 的中止信號。 abort 導(dǎo)致異常進(jìn)程終止。通常由檢測內(nèi)部錯誤或嚴(yán)重破壞約束的庫函數(shù)調(diào)用。例如,如果堆的內(nèi)部結(jié)構(gòu)被堆溢出損壞, malloc() 將調(diào)用 abort() |
SIGALRM SIGVTALRM SIGPROF |
如果你用 setitimer 這一類的報警設(shè)置函數(shù)設(shè)置了一個時限,到達(dá)時限時進(jìn)程會接收到 SIGALRM, SIGVTALRM 或者 SIGPROF。但是這三個信號量的含義各有不同,SIGALRM 計時的是真實時間,SIGVTALRM計時的是進(jìn)程使用了多少CPU時間,而 SIGPROF 計時的是進(jìn)程和代表該進(jìn)程的內(nèi)核用了多少時間。 |
SIGBUS | 總線發(fā)生錯誤時,進(jìn)程接收到一個SIGBUS信號。舉例來說,存儲器訪問對齊或者或不存在對應(yīng)的物理地址都會產(chǎn)生SIGBUS信號。 |
SIGCHLD | 當(dāng)子進(jìn)程終止、被中斷或被中斷后恢復(fù)時,SIGCHLD信號被發(fā)送到進(jìn)程。該信號的一個常見用法是指示操作系統(tǒng)在子進(jìn)程終止后清理其使用的資源,而不顯式調(diào)用等待系統(tǒng)調(diào)用。 |
SIGILL | 非法指令。當(dāng)進(jìn)程試圖執(zhí)行非法、格式錯誤、未知或特權(quán)指令時,SIGILL信號被發(fā)送到該進(jìn)程。 |
SIGKILL | 發(fā)送SIGKILL信號到一個進(jìn)程可以使其立即終止(KILL)。與SIGTERM和SIGINT相不同的是,這個信號不能被捕獲或忽略,接收過程在接收到這個信號時不能執(zhí)行任何清理。 以下例外情況適用: |
SIGINT | 來自鍵盤的中斷 (CTRL + C)。 KeyboardInterrupt |
SIGPIPE | 當(dāng)一個進(jìn)程試圖寫入一個沒有連接到另一端進(jìn)程的管道時,SIGPIPE信號會被發(fā)送到該進(jìn)程。 |
**SIGTERM ** | 終結(jié)信號。 KILL -15 |KILL |
SIGUSR1 SIGUSR2 |
用戶自定義信號 |
SIGWINCH | 終端窗口大小已變化 |
SIGHUP | 在控制終端上檢測到掛起或控制進(jìn)程的終止。 |
Reference:[signal-wikipedia](
信號函數(shù)
Python的信號庫中也有很多常用的函數(shù)
signal.alarm(time)
創(chuàng)建一個 SIGALRM 類型的信號,time為預(yù)定的時間,設(shè)置為0時取消先前設(shè)置的定時器
signal.pause()
可以使代碼邏輯處理過程睡眠,直到收到信號,然后調(diào)用對應(yīng)的handler。
import signal import os import time def do_exit(sig, stack): raise SystemExit('Exiting') signal.signal(signal.SIGINT, signal.SIG_IGN) signal.signal(signal.SIGUSR1, do_exit) print('My PID:', os.getpid()) signal.pause()
在執(zhí)行時,忽略了ctrl + c的信號,對USR1做退出操作
signal.setitimer(which, seconds, interval)
which: signal.ITIMER_REAL,signal.ITIMER_VIRTUAL 或 signal.ITIMER_PROF
seconds:多少秒后觸發(fā)which。seconds設(shè)置為0可以清除which的計時器。
interval:每隔interval秒后觸發(fā)一次
os.getpid()
獲得當(dāng)前執(zhí)行程序的pid
Windows下信號的使用
在Linux中,可以通過任何可接受的信號枚舉值作為信號函數(shù)的參數(shù)。在Windows中,SIGABRT, SIGFPE, SIGINT, SIGILL, SIGSEGV, SIGTERM, SIGBREAK。
當(dāng)signal handling需要參數(shù)怎么辦
在一些時候,signal handling的操作需要對應(yīng)主進(jìn)程傳遞進(jìn)來一些函數(shù),而在整個項目中執(zhí)行過程中的變量與 signal handling不處于一個作用域中,而signal.signal() 不能傳遞其他的參數(shù),這個時候可以使用 partial 創(chuàng)建一個閉包來解決這個問題。
例如:
import signal import os import sys import time from functools import partial """ 這里signal frame默認(rèn)參數(shù)需要放到最后 """ def signal_handler(test_parameter1, test_parameter2, signal_num, frame): print "signal {} exit. {} {}".format(signal_num, test_parameter1, test_parameter2) sys.exit(1) a=1 b=2 signal.signal(signal.SIGINT, partial(signal_handler, a, b) ) print('My PID:', os.getpid()) signal.pause()
忽略信號
signal定義了忽略接收信號的方法。為了實現(xiàn)信號的處理,需要使用signal.signal() 將默認(rèn)的信號與signal.SIG_IGN 注冊,即可忽略對應(yīng)的信號中斷,kill -9 不可忽略 。
import signal import os import time def receiveSignal(signalNumber, frame): print('Received:', signalNumber) raise SystemExit('Exiting') return if __name__ == '__main__': # register the signal to be caught signal.signal(signal.SIGUSR1, receiveSignal) # register the signal to be ignored signal.signal(signal.SIGINT, signal.SIG_IGN) # output current process id print('My PID is:', os.getpid()) signal.pause()
常用的信號
import signal import os import time import sys def readConfiguration(signalNumber, frame): print ('(SIGHUP) reading configuration') return def terminateProcess(signalNumber, frame): print ('(SIGTERM) terminating the process') sys.exit() def receiveSignal(signalNumber, frame): print('Received:', signalNumber) return signal.signal(signal.SIGHUP, readConfiguration) signal.signal(signal.SIGINT, receiveSignal) signal.signal(signal.SIGQUIT, receiveSignal) signal.signal(signal.SIGILL, receiveSignal) signal.signal(signal.SIGTRAP, receiveSignal) signal.signal(signal.SIGABRT, receiveSignal) signal.signal(signal.SIGBUS, receiveSignal) signal.signal(signal.SIGFPE, receiveSignal) #signal.signal(signal.SIGKILL, receiveSignal) signal.signal(signal.SIGUSR1, receiveSignal) signal.signal(signal.SIGSEGV, receiveSignal) signal.signal(signal.SIGUSR2, receiveSignal) signal.signal(signal.SIGPIPE, receiveSignal) signal.signal(signal.SIGALRM, receiveSignal) signal.signal(signal.SIGTERM, terminateProcess)
總結(jié)
到此這篇關(guān)于python中對信號處理的文章就介紹到這了,更多相關(guān)python信號處理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
通過實例了解Python str()和repr()的區(qū)別
這篇文章主要介紹了通過實例了解Python str()和repr()的區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-01-01Numpy將二維數(shù)組添加到空數(shù)組的實現(xiàn)
今天小編就為大家分享一篇Numpy將二維數(shù)組添加到空數(shù)組的實現(xiàn),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-12-12TensorFlow卷積神經(jīng)網(wǎng)絡(luò)MNIST數(shù)據(jù)集實現(xiàn)示例
這篇文章主要介紹了TensorFlow卷積神經(jīng)網(wǎng)絡(luò)MNIST數(shù)據(jù)集的實現(xiàn)示例的過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2021-11-11python pyinstaller打包exe報錯的解決方法
這篇文章主要給大家介紹了關(guān)于python pyinstaller打包exe報錯的解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者使用python具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11解決Python計算矩陣乘向量,矩陣乘實數(shù)的一些小錯誤
今天小編就為大家分享一篇解決Python計算矩陣乘向量,矩陣乘實數(shù)的一些小錯誤,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-08-08pytorch報錯問題:ValueError: num_samples should be
這篇文章主要介紹了pytorch報錯問題:ValueError: num_samples should be a positive integer value, but got num_samples=0的解決方案,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-02-02超詳細(xì)注釋之OpenCV Haar級聯(lián)檢測器進(jìn)行面部檢測
這篇文章主要介紹了OpenCV Haar級聯(lián)檢測器進(jìn)行面部檢測,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-09-09