私はマルチスレッドのプログラムを持っており、SIGINTを捕まえたいと思っています。私はsignal
インターフェイスを使ってみましたが、プログラムがthreading
を使用しているときに何もしないようです。マルチスレッドPythonプログラムの正しいシグナルAPIは何ですか?Python 2.7のスレッドセーフシグナルAPI
import signal
import sys
import threading
import os
# register my Ctrl-C handler
def signal_handler(signal, frame):
print('Signal.')
os._exit(0)
signal.signal(signal.SIGINT, signal_handler)
# stop the main thread
lock = threading.Lock()
with lock:
threading.Condition(lock).wait()
私は、Python 2.7.6を使用していますし、私のpip freeze
は言う:
Flask==0.10.1
Jinja2==2.9.6
Mako==1.0.7
MarkupSafe==1.0
PAM==0.4.2
Pillow==2.3.0
PyYAML==3.12
Saltscaffold==3.0.5
Twisted-Core==13.2.0
Twisted-Web==13.2.0
Werkzeug==0.9.4
adium-theme-ubuntu==0.3.4
apt-xapian-index==0.45
argparse==1.2.1
arrow==0.10.0
astroid==1.0.1
binaryornot==0.4.4
blinker==1.3
chardet==3.0.4
click==6.7
colorama==0.2.5
command-not-found==0.3
cookiecutter==1.5.1
debtagshw==0.1
defer==1.0.6
dirspec==13.10
duplicity==0.6.23
future==0.16.0
gevent==1.0
greenlet==0.4.2
gunicorn==17.5
html5lib==0.999
httplib2==0.8
itsdangerous==0.22
jinja2-time==0.2.0
lockfile==0.8
logilab-common==0.61.0
lxml==3.3.3
nose==1.3.7
oauthlib==0.6.1
oneconf==0.3.7.14.04.1
pexpect==3.1
piston-mini-client==0.7.5
poyo==0.4.1
pyOpenSSL==0.13
pycrypto==2.6.1
pycups==1.9.66
pygobject==3.12.0
pyinotify==0.9.4
pylint==1.1.0
pyserial==2.6
pysmbc==1.0.14.1
python-apt==0.9.3.5ubuntu2
python-dateutil==2.6.1
python-debian==0.1.21-nmu2ubuntu2
pyxdg==0.25
reportlab==3.0
requests==2.2.1
sessioninstaller==0.0.0
simplejson==3.3.1
six==1.10.0
software-center-aptd-plugins==0.0.0
ssh-import-id==3.21
system-service==0.1.6
unity-lens-photos==1.0
urllib3==1.7.1
vboxapi==1.0
wheel==0.24.0
whichcraft==0.4.1
wsgiref==0.1.2
xdiagnose==3.6.3build2
zope.interface==4.0.5
は、私も私のメインスレッドでsignal.pause()
をやってみましたが、それはまだ動作しません:
import threading, sys, signal, os
stderr_lock = threading.Lock()
def Log(module, msg):
with stderr_lock:
sys.stderr.write("%s: %s\n" % (module, msg))
class My_Thread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
Log("Init", "Initing.")
self.start()
def run(self):
while True:
Log("Run", "Running.")
for i in range(100):
My_Thread()
# trap ctrl-C in main thread
def handler(signal, frame):
print "GOT SIGINT!"
os._exit(0)
signal.signal(signal.SIGINT, handler)
signal.pause()
奇妙なことに、通常スレッドの数を100から87に減らすと機能します。
これまでにこの問題が発生しているようです:https://stackoverflow.com/questions/25676835/signal-handling-in-multi-threaded-python InterruptableThreadを定義する提案されたソリューションがあります。 –
https://stackoverflow.com/questions/46161884/python-2-7-how-to-catch-keyboard-interrupt-in-program-with-more-than-25-threads/でコメントしています。これは正確ですあなたがそこに見るのと同じ問題です。問題は、スレッド作成を 'try'ブロックに含めないことです。もっと精巧な説明のために私の答えを他の質問に見てください。 – JohanL
@ JohanL。シグナルをキャッチするコンテキストでは、ここには、スレッドがあれば 'signal'インターフェースだけに依存することができません。例外をキャッチする必要があります。戸部の答えに対する私のコメントを見てください。 –