python學習筆記——信號模塊signal

基於python學習筆記——多進程間通訊——Linux信號基礎的學習基礎,進一步學習Python標準庫中的signal模塊。html

儘管signal是python中的模塊,可是主要針對UNIX平臺(好比Linux,MAC OS),而Windows內核中因爲對信號機制的支持不充分,因此在Windows上的Python不能發揮信號系統的功能。python

signal模塊負責python程序內部的信號處理;典型的操做包括信號處理函數、暫停並等待信號,以及定時發出SIGALRM等;segmentfault

1 signal基本信號名

引入模塊: import signal 函數

signal.SIGHUP   # 鏈接掛斷;
signal.SIGILL   # 非法指令;
signal.SIGINT   # 終止進程(ctrl+c);
signal.SIGTSTP  # 暫停進程(ctrl+z);
signal.SIGKILL  # 殺死進程(此信號不能被捕獲或忽略);
signal.SIGQUIT  # 終端退出;
signal.SIGTERM  # 終止信號,軟件終止信號;
signal.SIGALRM  # 鬧鐘信號,由signal.alarm()發起;
signal.SIGCONT  # 繼續執行暫停進程;

2 經常使用信號處理函數

2.1 設置發送SIGALRM信號的定時器

 signal.alarm(time) post

參數:time爲時間參數學習

功能:在time時間後,向進程自身發送SIGALRM信號url

import signal
import time

signal.alarm(4)#4s後終止程序

while True:
    time.sleep(1)
    print("學習python中...")

運行spa

學習python中...
學習python中...
學習python中...
鬧鐘

 

當在一個程序中出現兩個signal.alarm()函數時操作系統

import signal
import time

print(signal.alarm(3)) # 0
time.sleep(1)
print(signal.alarm(4)) # 2

while True:
    time.sleep(1)
    print("學習python中...")

運行.net

0
2
學習python中...
學習python中...
學習python中...
鬧鐘

注意:在一個進程中,只能設置一個時鐘,若是設置第二個則會覆蓋第一個的時間,返回地一個的剩餘時間,第一個鬧鐘返回0。

 

使用signal.pasue阻塞函數:

signal.pause() Wait until a signal arrives。讓進程進程暫停,以等待信號(什麼信號都可);也即阻塞進程進行,接收到信號後使進程中止

import signal
import time

print(signal.alarm(3)) # 0
time.sleep(1)
print(signal.alarm(4)) # 3

#阻塞等待信號的發生,如論什麼信號均可以
signal.pause()

while True:
    time.sleep(1)
    print("學習python中...")

運行

0
2
鬧鐘

 

2.2 設置信號處理函數

 signal.signal(sig, handler) 

功能:按照handler制定的信號處理方案處理函數

參數

sig:擬需處理的信號,處理信號只針對這一種信號起做用sig

hander:信號處理方案

    在信號基礎裏提到,進程能夠無視信號、可採起默認操做、還可自定義操做;當handler爲下列函數時,將有以下操做:

    SIG_IGN:信號被無視(ignore)或忽略

    SIG_DFL:進程採用默認(default)行爲處理

   function:handler爲一個函數名時,進程採用自定義函數處理

   *SIGSTOP SIGKILL不能處理,只能採用

 

示例1

import signal

#6s後終止程序
signal.alarm(6)

#遇到SIGINT ctrl+c時,忽略SIG_IGN
signal.signal(signal.SIGINT,signal.SIG_IGN)

signal.pause()

運行後6s 打印出: 鬧鐘 

若是在運行中在鍵盤中輸入CTRL+C也無濟於事,此時輸出結果 ^C^C^C^C^C^C^C^C鬧鐘 

緣由分析

(1)signal.signal(signal.SIGINT, signal.SIG_IGN) 表示遇到信號SIGINT  CTRL + C,時,忽略SIG_IGN該信號。

因此在程序運行中從鍵盤輸入ctrl+c(在終端上顯示 ^C )時無效。

(2)當signal.alarm(6)計時6秒後,直接在終端上輸出 「鬧鐘」 後退出。

(3)signal.pause()是爲了阻塞進程,等待信號。若是沒有這句話,能夠在程序中更變爲

while True:
    pass

效果同樣,若是沒有這段代碼,則沒有直接運行結束,終端上沒有任何輸出顯示。注意:這裏的signal.alarm()是在程序運行中,6秒後中止進程。

 

示例2 

進程中默認信號方式處理

import signal
#6s後終止程序
signal.alarm(6)
signal.signal(signal.SIGALRM,signal.SIG_DFL)
signal.pause()

運行後終端顯示  鬧鐘

 

示例3

有些原操做系統規定了的進程收到信號後的默認行爲,使用signal.signal()能夠經過綁定信號處理函數來修改進程收到信號後的行爲,實現個性化處理。

也即改變原默認行爲,可是SIGTOP和SIGKILL兩個信號的默認行爲是不可更變的。

from signal import *
import time

def handler(signum,frame):
    if signum == SIGALRM:
        print('時間到了')
    elif signum == SIGINT:
        print("CTRL + C 無效")

alarm(5)
signal(SIGINT,handler)
signal(SIGALRM,handler)


while True:
    print('Waiting....')
    time.sleep(2)

運行結果

Waiting....
Waiting....
Waiting....
時間到了
Waiting....
^CCTRL + C 無效
Waiting....
^CCTRL + C 無效
Waiting....
^\退出 (核心已轉儲)

說明:

(1)signal.signal() 經過綁定函數更變了信號的處理方式

(2)若是沒有改變alarm()信號的處理方式,signal.alarm()在運行5s後會將終止程序並輸出「鬧鐘」字樣

(3)從設備終端鍵盤輸入ctrl+c無效後,此時能夠輸入ctrl+\退出程序

(4)def handler(signum,frame)中frame,第一個參數是用來識別信號(signum),第二個信號是用來得到信號發生時,進程棧的情況(stack frame對象),這兩個參數都是由signal.signal()函數傳遞的。 參考 Frame objects

 

示例4

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')

運行(運行後設備終端鍵盤輸入ctrl+z)

^ZI received:  20
End of Signal Demo

說明:

(1)signal.signal()函數來預設信號處理函數;

(2)當程序執行signal.pause()來讓進程暫停(被阻塞)以等待信號,此時,按下ctrl + z 向該進程發送SIGTSTP信號,當信號signal.SIGTSTP信號傳遞給該進程後,進程從被阻塞中恢復,並根據預設,執行SIGTSTP的信號處理函數myHandler()。

(3)myHandler()的兩個參數一個用來識別信號(signum),另外一個用來得到信號發生時,進程棧的情況(stack frame);這兩個參數都是有signal.signal()函數傳遞的。

(4)進程並不必定要使用signal.pause()暫停以等待信號,它也能夠在進行工做中接受信號,好比將上面的signal.pause()改成一個須要長時間工做的循環或死循環。

 

總結:經常使用信號處理函數:

 

3 經常使用信號處理函數

 signal.signal(signalnum, handler)  設置信號處理的函數

 signal.alarm(time) 設置發送SIGALRM信號的定時器

 os.kill 這個不屬於signal模塊,但其可使用給某一進程發送信號

 

參考:

Python模塊之信號(signal)和 Python模塊:signal(同樣)

初步理解Python進程的信號通信

Python 信號處理 signal 模塊

進程間通訊的方式——信號、管道、消息隊列、共享內存

相關文章
相關標籤/搜索