signal モジュールの紹介
最近、Signal はプロセス間通信や非同期処理に使用できる、Linux のシグナル関連のコンテンツを読んでいます。 Python 標準ライブラリは、信号の処理に使用できる信号パッケージを提供します。ここで説明するのは、Unix システムにおける Python のシグナル モジュールです。
シグナルの簡単な例
公式ドキュメントにはそのような例があります:
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 をトリガーします。 5 秒以内にファイルが正常に開かれると、タイマーはクリアされます。
信号の説明
基本的な信号名
import signal signal.SIGABORT signal.SIGHUP # 连接挂断 signal.SIGILL # 非法指令 signal.SIGINT # 连接中断 signal.SIGKILL # 终止进程(此信号不能被捕获或忽略) signal.SIGQUIT # 终端退出 signal.SIGTERM # 终止 signal.SIGALRM # 超时警告 signal.SIGCONT # 继续执行暂停进程 等等...
一般的に使用される信号処理関数
signal.signal(signalnum, handler)
信号処理関数を設定します
signal.alarm(time)
SIGALRM信号を次のように設定します送信されるタイマー
os.kill
これはシグナルモジュールに属しませんが、特定のプロセスにシグナルを送信するために使用できます
シグナルの使用例
例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
上記の例は実装しています関数の実行タイムアウトを設定し、デフォルトの 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 を実行すると、プログラムは 2 秒ごとに lib.py 内のscrape_me_bro() メソッドを呼び出します。このとき、lib.py 内のメソッドが変更されると、実行中のプロセスが変更されます。 SIGHUP シグナルを送信すると、scrape.py が呼び出され、lib.py がリロードされ、変更されたscrape_me_bro() メソッドがループで実行されます。