首頁 >後端開發 >Python教學 >Python 訊號處理 signal 模組

Python 訊號處理 signal 模組

高洛峰
高洛峰原創
2016-11-22 10:12:591849瀏覽

signal模組簡介

最近在看Linux signal 相關內容,signal可以被用來進程間通訊和非同步處理。 Python標準函式庫提供了signal套件可以用來處理訊號相關。這裡討論的是Unix系統中Python的signal模組。

signal簡單範例

官方文件上有這樣的範例:

import signal, os

# 定义一个信号处理函数,该函数打印收到的信号,然后raise IOError
def handler(signum, frame):
    print 'Signal handler called with signal', signum
    raise IOError("Couldn't open device!")

# 对SIGALRM(终止)设置处理的handler, 然后设置定时器,5秒后触发SIGALRM信号
signal.signal(signal.SIGALRM, handler)
signal.alarm(5)

# This open() may hang indefinitely
fd = os.open('/dev/ttyS0', os.O_RDWR)

signal.alarm(0)          # 关闭定时器

該範例實現的功能是,為了防止開啟一個文件出錯或其他異常一直處於等待的狀態,設定一個定時器,5秒後觸發IOError。若5s內正常開啟文件,則清除定時器。

signal說明

基本的訊號名稱

import signal

signal.SIGABORT
signal.SIGHUP  # 连接挂断
signal.SIGILL  # 非法指令
signal.SIGINT  # 连接中断
signal.SIGKILL # 终止进程(此信号不能被捕获或忽略)
signal.SIGQUIT # 终端退出
signal.SIGTERM # 终止
signal.SIGALRM  # 超时警告
signal.SIGCONT  # 继续执行暂停进程

等等...

常用訊號處理函數

signal.signal(signalnum, handler)

設定訊號處理的函數
定時器

os.kill


這個不屬於signal模組,但其可以使用給某一進程發送信號

signal使用範例


範例1

# From project httpscreenshot-master, under directory , in source file httpscreenshot.py.
def timeoutFn(func, args=(), kwargs={}, timeout_duration=1, default=None):
    import signal

    class TimeoutError(Exception):
        pass

    def handler(signum, frame):
        raise TimeoutError()

    # set the timeout handler
    signal.signal(signal.SIGALRM, handler)
    signal.alarm(timeout_duration)
    try:
        result = func(*args, **kwargs)
    except TimeoutError as exc:
        result = default
    finally:
        signal.alarm(0)
        signal.signal(signal.SIGALRM, signal.SIG_DFL)

    return result

上面這個範例實作了預設值執行這個範例結果的功能。先是設定了一個超時處理函數,在函數中拋出自定義的拋出異常。在執行函數前設定了 signal.alarm ,當超出時間後觸發拋出異常 SIGALRM, 然後捕獲這個異常設定預設值,最後做下清理工作將定時器取消,並且將對 SIGALRM 的處理設為預設。

範例2

這個範例來自這裡。 需求是動態載入python導入的模組,也就是說,當導入的模組程式碼更新時,希望可以立即更新引用的程式碼。範例如下:

# lib.py
def scrape_me_bro():
        print "Scraping is fun"



#scrape.py
import time
import signal
import lib

def scrape():
        # Assume we are hitting Streaming API
        # and doing something buzzwordy with it
        while True:
                lib.scrape_me_bro()
                time.sleep(2)

def reload_libs(signum, frame):
        print "Received Signal: %s at frame: %s" % (signum, frame)
        print "Excuting a Lib Reload"
        reload(lib)

# Register reload_libs to be called on restart
signal.signal(signal.SIGHUP, reload_libs)

# Main
scrape()

當執行scrape.py時,程式會每兩秒呼叫一次lib.py中的 scrape_me_bro() 方法,這時候如果lib.py裡的方法變化了,向執行scrape.py的進程傳送 SIGHUP 訊號,那麼它會重新載入lib.py,這樣會接著迴圈執行修改後的 scrape_me_bro() 方法。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn