シグナルハンドラからのforkするのは安全か? (2) シングルスレッドの場合
シングルスレッドの場合、シグナルハンドラからforkする場合には次のどちらかの方法を取れば安全です(どちらも子プロセスの話)。
- fork直後に(printfを含む如何なる関数も呼ばずに)すぐにexecする
- execしない場合、子プロセスは自身が消滅(exit)するまで「非同期シグナルセーフ」関数だけを呼ぶ*1
規格にはこのように書いてあります。
Consequently, to avoid errors, the child process may only execute async-signal-safe operations until such time as one of the exec functions is called.
しかし後者の方法はちょっと現実的ではないでしょう。非同期シグナルセーフ関数なんて数えるほどしかないのですから、子プロセスの全処理をそれだけで書くのは難しい場合が多いと思います。なんたってprintfすら使えないのですから。
というわけで、前者の方法をとるか、もしそれがムリならシグナルハンドラの中ではforkせず、ハンドラ外でforkするようにするのが一番です。
なお、親プロセスは、普通に "シグナルハンドラを脱出するまでは" 非同期シグナルセーフ関数だけ呼ぶように作成すればOKです。
→続き
*1:ちなみにexit(3)は非同期シグナルアンセーフ関数ですから、_exit(3)で終了しないとダメですね:-)