Python のスクリプトを書いています。

最初は signal を受信したらハンドラ内でファイル I/O 処理など様々な処理を書いていました。スクリプトを実行し、kill -TERM <PID> を実行するとシグナルハンドラ handler() が呼ばれ、様々な処理をするコードです。

import signal
import time
import os


def handler(num, frame):
    print("handler")
    # do something


signal.signal(signal.SIGTERM, handler)
print("sleep... {0}".format(os.getpid()))
time.sleep(60)

が、ふと、signal ハンドラ内で重い処理をおこなっていいのか疑問に思い、ググったり、いろいろ調べたところ Linuxプログラミングインタフェース「21章 シグナルハンドラの設計」に以下のように書いてありました。

「すべてのシステムコール、ライブラリ関数が、シグナルハンドラ内で安全に実行できる訳ではありません。その理由を理解するには、リエントラントな関数、および非同期シグナルセーフな関数という 2 つの概念が必要になります。(p.444)

ここで、「非同期シグナルセーフ」はいわゆるスレッドセーフのことのようです。

つまり、ファイル I/O 等の処理はたとえばマルチスレッドとして実装し、シグナルハンドラからはスレッドを起こすだけ、といったようにしないといけない。と理解したのですが、このような理解であっているでしょうか?

たとえばこのような実装をイメージしています:

import signal
import threading
import time
import os

event = threading.Event()


def funcA():
    print("start funcA")
    event.wait()
    print("end funcA")


def handler(num, frame):
    print("handler")
    event.set()


signal.signal(signal.SIGTERM, handler)
th = threading.Thread(target = funcA)
th.start()
print("sleep... {0}".format(os.getpid()))
time.sleep(60)