Last active
February 3, 2023 12:20
-
-
Save fortune/acfa75ca4095b858894574e4b505079a to your computer and use it in GitHub Desktop.
Python プロセスのシグナル制御のサンプルコード
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Process をシグナルで制御するサンプルコード | |
Python でシグナルハンドラを設定しても、低水準 (C言語) のシグナルハンドラ内で実行されるわけではない。 | |
低水準のシグナルハンドラがフラグを立て、Python コードを実行する VM が 後で、対応するシグナルハンドラを実行できるようにする。 | |
シグナルが受信されたとき、時間のかかる C 拡張を実行していたりすると、そのシグナルに設定しておいたシグナルハンドラが | |
実行されるまで時間がかかることがある。VM がフラグを見るのは、C 拡張が終わった後だろうから。とはいえ、デフォルト動作であるなら | |
そのようなことはない。たとえば、SIGTERM に対するデフォルト動作はプロセス終了なので、Python でそれにシグナルハンドラを | |
設定していなければ、SIGTERM 発生時に C 拡張を実行していたとしても直ちに終了する。 | |
SIGINT については、Python の KeyboardInterrupt 例外をスローするシグナルハンドラが設定されている。これが望む動作でないなら上書きすればいい。 | |
""" | |
from multiprocessing import Process | |
import signal | |
import time | |
def handler(signo, _): | |
""" | |
シグナルハンドラ | |
signo -- ハンドラを起動したシグナルの番号 | |
_ -- スタックフレーム(ここでは使用しない) | |
""" | |
signal.signal(signo, signal.SIG_DFL) | |
print('Catche ' + str(signo)) | |
def worker(signo): | |
""" | |
サブプロセス本体となる関数 | |
signo -- 対象とするシグナル番号 | |
""" | |
signal.signal(signo, handler) # ハンドラを設定 | |
#signal.signal(signo, signal.SIG_IGN) # シグナルを無視 | |
#signal.signal(signo, signal.SIG_DFL) # デフォルト動作 | |
i = 0 | |
while True: | |
print(i) | |
i += 1 | |
time.sleep(1) | |
p = Process(target=worker, args=(signal.SIGTERM,), daemon=True) | |
p.start() | |
p.terminate() # "Catch 15" と出力 | |
p.terminate() # 終了する | |
p.exitcode # SIGTERM のシグナル番号は 15 なので、-15 になる。 | |
# プロセスが終了したとき、それはゾンビプロセスになる。p.exitcode または p.join() または p.is_alive() を実行すると、 | |
# ゾンビ状態が解消される。また、別の新たなプロセスを開始しても解消される。 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment