スレッドを使用し、多くのHTTPリクエストを行うpythonスクリプトがあります。HTTPリクエスト(urllib2を使用)が読み取りを行っている間、それはブロックされておりCtrlC、プログラムを停止するために応答していません。これを回避する方法はありますか?
スレッドを使用し、多くのHTTPリクエストを行うpythonスクリプトがあります。HTTPリクエスト(urllib2を使用)が読み取りを行っている間、それはブロックされておりCtrlC、プログラムを停止するために応答していません。これを回避する方法はありますか?
回答:
Windowsでは、唯一の確実な方法はを使用することCtrlBreakです。すべてのPythonスクリプトを即座に停止します!
(一部のキーボードでは、「Break」が「Pause」とラベル付けされていることに注意してください。)
Break
?入力するにはどうすればよいですか?
Pythonプログラムの実行中にCtrl+ cを押すと、PythonでKeyboardInterrupt
例外が発生します。多くのHTTPリクエストを行うプログラムには、多くの例外処理コードが含まれている可能性があります。- ブロックのexcept
部分で、どの例外をキャッチするかを指定していない場合は、発生したものを含むすべての例外をキャッチします。適切にコーディングされたpythonプログラムは、python例外階層を利用して、から派生した例外のみをキャッチします。try
except
KeyboardInterrupt
Exception
#This is the wrong way to do things
try:
#Some stuff might raise an IO exception
except:
#Code that ignores errors
#This is the right way to do things
try:
#Some stuff might raise an IO exception
except Exception:
#This won't catch KeyboardInterrupt
コードを変更できない場合(または変更を有効にするためにプログラムを強制終了する必要がある場合)、すばやくCtrl+を押してみてくださいc。最初のKeyboardInterrupt
例外はプログラムをtry
ブロックからノックアウトし、うまくいけばKeyboardInterrupt
、プログラムがtry
ブロックの外にあるときに、後の例外の1つが発生します。
Pythonシェルで実行されている場合はCtrl+を使用しZ、そうでない場合はpython
プロセスを見つけて強制終了します。
^Z
-> [1]+ Stopped
-> kill %1
ジョブ#1(またはbashが
fg
するとすぐに元に戻ります。
Ctrl+Z
はpythonスクリプトを停止する適切な方法ではないため、一時停止したプロセスを再開する予定がない限り避けてください。
割り込みプロセスはハードウェアとOSに依存します。したがって、Pythonスクリプトをどこで実行するかによって、動作が大きく異なります。たとえば、WindowsマシンにはCtrl+ C(SIGINT
)とCtrl+ Break(SIGBREAK
)があります。
したがって、SIGINTはすべてのシステムに存在し、処理およびキャッチできますが、SIGBREAK信号はWindows固有であり(CONFIG.SYSで無効にすることができます)、実際にはBIOSによって割り込みベクトルINT 1Bhとして処理されます。他のものよりもはるかに強力です。したがって、* nix風味のOSを使用している場合、その信号はそこに存在しないため、実装によって異なる結果が得られますが、他のOSは存在します。Linuxでは、次の方法で利用可能な信号を確認できます。
$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGEMT 8) SIGFPE 9) SIGKILL 10) SIGBUS
11) SIGSEGV 12) SIGSYS 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGURG 17) SIGSTOP 18) SIGTSTP 19) SIGCONT 20) SIGCHLD
21) SIGTTIN 22) SIGTTOU 23) SIGIO 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGPWR 30) SIGUSR1
31) SIGUSR2 32) SIGRTMAX
だからあなたがキャッチしたいなら CTRL+BREAK
、LinuxシステムでシグナルそのキーをマップしたPOSIXシグナルを確認する必要があります。一般的なマッピングは次のとおりです。
CTRL+\ = SIGQUIT
CTRL+D = SIGQUIT
CTRL+C = SIGINT
CTRL+Z = SIGTSTOP
CTRL+BREAK = SIGKILL or SIGTERM or SIGSTOP
実際、Linuxでは、さらに多くの機能を利用できます。 SysRq(システム要求)キーが独自の ...
この投稿は古いですが、私は最近、同じ問題に遭遇したCtrl+ CLinux上でPythonスクリプトを終了していません。Ctrl+ \(SIGQUIT
)を使用しました。
Ctrl+ DWindowsとLinuxの違い
Python 3.6以降、PythonインタープリターはLinuxとWindowsではCtrl+の扱いがC異なることがわかりました。Linuxの場合、Ctrl+ C働くだろう、ほとんどがWindows上で期待通りにCtrl+ C 、ほとんどのPythonのような呼び出しをブロックし実行している場合は特に動作しないthread.join
か、ウェブ応答を待っています。time.sleep
ただし、では機能します。ここにあります素敵な説明 Pythonインタプリタで何が起こっているのかの。Ctrl+はをC生成することに注意してくださいSIGINT
。
解決策1:Ctrl+ Breakまたは同等のものを使用する
SIGBREAK
OSの下位レベルで生成され、Pythonインタープリターを終了するターミナル/コンソールウィンドウで以下のキーボードショートカットを使用します。
Mac OSおよびLinux
Ctrl+ Shift+ \またはCtrl+\
窓:
解決策2:Windows APIを使用する
以下は、Windowsを検出し、コンソールにCtrl+のカスタムハンドラーをインストールする便利な関数Cです。
#win_ctrl_c.py
import sys
def handler(a,b=None):
sys.exit(1)
def install_handler():
if sys.platform == "win32":
import win32api
win32api.SetConsoleCtrlHandler(handler, True)
上記のように使用できます:
import threading
import time
import win_ctrl_c
# do something that will block
def work():
time.sleep(10000)
t = threading.Thread(target=work)
t.daemon = True
t.start()
#install handler
install_handler()
# now block
t.join()
#Ctrl+C works now!
解決策3:ポーリング方法
この方法は、不必要にプロセッサと電力を消費してパフォーマンスに悪影響を与えるため、この方法はお勧めしません。
インポートスレッドインポート時間
def work():
time.sleep(10000)
t = threading.Thread(target=work)
t.daemon = True
t.start()
while(True):
t.join(0.1) #100ms ~ typical human response
# you will get KeyboardIntrupt exception
ctrl + c
終了せずにが表示されKeyboardInterrupt
ます。
それらは役立つかもしれません。
タスクマネージャーを開いて(Ctrl + Alt + Deleteを押してからタスクマネージャーに移動)、Pythonを探してサーバーを呼び出します(例)_go_app(命名規則は_language_app)。
_go_appタスクを終了するとサーバーが終了するため、ブラウザーでそこに移動すると「予期せず終了した」と表示され、git bashも使用します。サーバーを起動すると、bashのシェルでサーバーから抜け出すことができませんctrl + cまたはctrl + pauseを使用しますが、Pythonタスク(63.7 MBを使用するタスク)を終了すると、bashのサーバースクリプトから抜け出し、git bashシェルを使用できるようになります。