【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による停止を安全に扱うには、プログラムの規模・性質に応じた設計が求められます。
それぞれの手法のメリット・制約を理解し、自身のユースケースに最適な方式を選びましょう。