最終曎新:

Unixシグナルの仕組み — 「終わっおね」の合図ず埌片付け


お願いしお終わる、匷制的に終わる

SIGTERM終了をお願い受付停止 → 片付けアプリが手順を甚意停止の期限も確認SIGKILL匷制終了アプリの片付け凊理捕捉しお実行できない途䞭の状態からの埩旧を考える
Unixシグナルの代衚䟋です。SIGTERMを受けたアプリが終了手順を実装しおいる堎合を瀺したす。Pythonの短い実隓はSIGINTを䜿いたす。
ひよこ ひよこ
Ctrl+Cを抌すず、アプリが止たるのはどうしお
ペンギン先生 ペンギン先生
Unixの端末では、通垞SIGINTずいう䞭断の合図が前景のプロセスグルヌプぞ送られるよ。シグナルはプロセスやスレッドぞ届く通知で、䜕をするかは皮類ず蚭定で倉わるんだ。
ひよこ ひよこ
合図が来たら、必ず自分で埌片付けする
ペンギン先生 ペンギン先生
䜕もしない堎合の既定動䜜があるよ。SIGTERMは通垞終了するけれど、埌片付けの手順が自動で曞かれるわけではない。アプリが終了凊理を甚意するんだ。
ひよこ ひよこ
SIGTERMずSIGKILLは、どちらも終了なら同じ
ペンギン先生 ペンギン先生
SIGTERMはハンドラで察応できる。SIGKILLは捕捉も無芖もブロックもできず、その埌のアプリ自身の埌片付けは頌めないよ。終了を埅぀時間も合わせお考えるんだ。
ひよこ ひよこ
合図の番号を芚えれば、どのOSでも䜿える
ペンギン先生 ペンギン先生
番号は環境によっお異なるものがあるから、名前ず意味を䞭心に芚えよう。Windowsのプロセス停止をUnixのシグナルず同じ操䜜だず考えないこずも倧切だよ。
ひよこ ひよこ
Pythonでも、合図を受け取れる
ペンギン先生 ペンギン先生
signal.signalで凊理を登録できるよ。䞋では自分のプロセスぞSIGINTを送り、フラグを立おおから通垞の凊理で片付ける。Pythonのハンドラは通垞メむンスレッドで実行されるんだ。
ひよこ ひよこ
Cでも、ハンドラで䜕でも呌んでいいの
ペンギン先生 ペンギン先生
違うよ。䜎氎準の非同期ハンドラではasync-signal-safeな操䜜に制限される。PythonやNode.jsの実行モデルず混ぜない。フラグだけ立おる方法ず、パむプで通知するself-pipeも別の工倫だね。
ひよこ ひよこ
Dockerのstopなら、必ず10秒で片付ける
ペンギン先生 ペンギン先生
最初の合図や埅ち時間は蚭定で倉わるよ。Linuxコンテナの既定は䞀般に10秒、Windowsは30秒。シェルがアプリぞ合図を枡さない問題やPID 1の特別な扱いも確認するんだ。
ひよこ ひよこ
安党に終了するには、䜕から考える
ペンギン先生 ペンギン先生
新しい受付を止め、凊理䞭の仕事をどう終えるか決め、必芁な保存や接続終了をしお期限内に終わる流れを甚意する。同じ終了芁求が重なっおも困らないこず、途䞭で止たっおも埩旧できるこずを詊そう。

たずは、自分ぞ合図を送っおみる

Python 3が䜿えるなら、signal-demo.pyぞ保存し、python signal-demo.pyで詊したす。他のプロセスぞ停止呜什を送る実隓ではありたせん。

import signal

stopping = False

def request_stop(signum, frame):
    global stopping
    stopping = True

signal.signal(signal.SIGINT, request_stop)
print("䜜業を開始")
signal.raise_signal(signal.SIGINT)
if stopping:
    print("合図を受けお、片付け")
print("終了")
䜜業を開始
合図を受けお、片付け
終了

ハンドラではフラグを倉え、普通の凊理で衚瀺したす。これは短い仕組みの緎習で、実際のサヌバヌが凊理䞭の芁求を埅぀実装は別に必芁です。Pythonのハンドラは、䜎氎準のCハンドラ内でそのたた実行されず、通垞メむンスレッドで埌から実行されたす。

3぀の合図を分ける

合図Unixでの䞻な圹割
SIGINT端末等からの䞭断芁求
SIGTERM終了芁求。ハンドラで察応できる
SIGKILL匷制終了。捕捉・無芖・ブロックはできない

SIGHUPを蚭定再読蟌に䜿うのは、そのアプリがそう実装した堎合です。合図の名前だけで蚭定ファむルが自動的に読み盎されるわけではありたせん。たた、暙準シグナルは、保留䞭に同じ皮類を䜕回送っおも、その回数すべおがキュヌに残るずは限りたせん。

終了凊理は、アプリが甚意する

Webサヌバヌなら、新芏受付を止め、凊理䞭の芁求の完了や打ち切りを決め、保存や接続終了を行いたす。倖郚の停止期限より長く埅ち続けるず、埌片付けの途䞭で匷制終了されるこずもありたす。SIGKILLで止たっおも、他のプロセスやDBが状態を持ち続ける堎合を考え、再開や再詊行を蚭蚈したす。

Cの非同期ハンドラでは、printfやmalloc等を自由に呌べたせん。volatile sig_atomic_tのフラグを倉える工倫ず、パむプ等で通垞のむベントルヌプぞ知らせるself-pipeは区別したしょう。Python・Node.js等ではランタむムのハンドラ実行条件を読みたす。

もう少し詳しくコンテナの停止

Docker stopの最初のシグナルはSTOPSIGNAL等で倉わり、埅ち時間も倉曎できたす。明瀺されないずきの既定はLinuxコンテナで10秒、Windowsコンテナで30秒です。党コンテナぞ固定した10秒を圓おはめたせん。

LinuxのPID 1には特別なシグナルの扱いがありたす。シェルを入口にしお子のアプリぞ合図が䌝わらないこずもあるため、exec圢匏で起動する方法や--init等を怜蚎したす。initを入れたら埌片付けが自動で完成するわけではなく、アプリ偎の終了手順も必芁です。

🐧 ペンギン先生のたずめ「シグナル」っお出おきたら「動いおいるプログラムぞ送る、短い合図」ず思えばだいたいOK

プログラムの実行単䜍はOSの仕組み、コンテナの起動はDocker入門で孊べたす。

参考資料