Thread-Safe Signal API in Python 2.7

2019-09-22 01:43发布

I have a multi-threaded program and want to catch SIGINT. I tried using the signal interface but it appears to stop doing anything when the program uses threading. What is the correct signal API for multi-threaded python programs?

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()

I am using python 2.7.6 and my pip freeze says:

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

I also tried doing signal.pause() in my main thread, but it still doesn't work:

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()

Curiously, it usually works if you decrease the number of threads from 100 to 87.

1条回答
迷人小祖宗
2楼-- · 2019-09-22 02:15

Only the main thread is listening to SIGINT. Make sure all threads are listening to the SIGINT value.

查看更多
登录 后发表回答