【Python】プログラムをCtrl+Cで安全に停止させる3つの方法【SIGINT対応】
Pythonスクリプトを実行中にCtrl+C
で安全に停止させたい場合、**シグナル(SIGINT)**の正しい扱いが重要です。
try/except KeyboardInterruptで簡潔に捕捉する
🔍 概要
Ctrl+C
はPythonにおいてKeyboardInterrupt
例外として送出されます。try/except
でこの例外を捕捉し、終了処理を実装できます。
|
|
✅ ポイント
- シンプルで小規模スクリプトに最適
- SIGINT(Ctrl+C)のみ対象、他のシグナルには非対応
signal.signalでSIGINTに専用ハンドラを登録
🔍 概要
Pythonのsignal
モジュールでSIGINTにカスタムハンドラを割り当て、独自のシャットダウン処理を実行できます。
|
|
✅ ポイント
- 複数のシグナル(SIGTERM等)にも拡張可能
- Webサーバーやデーモンなど中〜大規模向き
現在の処理を完了後、次ループで停止する
🔍 概要
Ctrl+C
を受け取っても現在の処理を完了させ、次ループに入る前に停止します。
バッチ処理や重たい処理を中断せず安全に終わらせたいケースに適します。
|
|
✅ ポイント
- 時間のかかる処理を強制終了せずに安全に終えたいときに有効
- 実行タイミングを明示的に制御できる
使い分けの指針
ケース | 推奨方法 |
---|---|
小規模スクリプト | try/except KeyboardInterrupt |
コンテナやデーモン | signal.signal でSIGINT対応 |
タスクの整合性を保ちたい | ループ終了制御型 |
応用テクニック・拡張例
- ✅ ログ連携:
logging
モジュールを使って、終了原因や実行履歴を記録 - ✅ 複数シグナル対応:
SIGTERM
/SIGHUP
などもsignal.signal()
で捕捉 - ✅ 非同期処理対応:
asyncio.get_event_loop().add_signal_handler()
を活用 - ✅ マルチスレッド処理:
threading.Event()
と連携し安全にスレッド停止 - ✅ ユニットテスト:
pytest
+os.kill()
等で終了処理の動作確認
参考リンク
まとめ
PythonでCtrl+C
による停止を安全に扱うには、プログラムの規模・性質に応じた設計が求められます。
それぞれの手法のメリット・制約を理解し、自身のユースケースに最適な方式を選びましょう。