当我使用多级/嵌套(线程级别2)线程时,不会调用Python信号处理程序。不确定究竟是什么导致了这一点。相关代码如下。
作为多级/嵌套线程的替代方法,我可以尝试使用多进程+线程或队列+线程。但我真的想知道这个问题的原因或任何解决方案。好像它与python Global Interpreter Lock(GIL)有关。
在python中处理多级线程应用程序信号的最佳方法是什么?
CODE 的
#!/usr/bin/python
import threading, sys
import signal, time
threads = []
threadsL1 = []
threadsL1_statusflag = False
stopExecutionFlag = False
class MyThread(threading.Thread):
global stopExecutionFlag
def __init__(self, name):
super(MyThread, self).__init__()
self._tname = name
self._terminate = False
#threading.Thread.__init__(self)
def terminate(self):
print "L2[%s] : calling terminate" % self._tname
self._terminate = True
stopExecutionFlag = True
def run(self):
print "L2[%s]: Running" % self._tname
while True:
if stopExecutionFlag:
print "L2[%s] : stopExecutionFlag is set. Exiting now !!"
break
print "L2[%s]: Sleeping for 2 sec" % self._tname
time.sleep(2)
print "L2[%s]: Thread stopped" % self._tname
def startThreadL2(name):
global threads
print "L1[%s] Inside startThreadL2" % name
t1 = MyThread(name)
t1.start()
threads.append(t1)
print "L2[%s] Thread started and appended to threads array" % name
def joinThreadsL2():
global threads
print "L2 Inside joinThreadsL2()"
for thread in threads:
thread.join()
print "All threads finished execution"
def stopThreadsL2():
global stopExecutionFlag
stopExecutionFlag = True
print "Inside stopThreadsL2()"
joinThreadsL2()
def startThreadL1_and_wait():
global threadsL1
print "Main() calling startThreadL1()"
for i in range(1,3):
t1 = threading.Thread(target=startThreadL2, args=("T%d" % i,))
t1.start()
threadsL1.append(t1)
print "L1[%s] : Thread started" % ("T%d" % i)
print "L1[%s] : Waiting for all threads to finish"
for t2 in threadsL1:
t2.join()
print "L1[%s] : All L1 threads finished"
threadsL1_statusflag = True
def stopThreadsL1():
global threadsL1_statusflag
if not threadsL1_statusflag:
print "L1[%s] : Waiting for all threads to finish"
for t2 in threadsL1:
t2.join()
print "L1[%s] : All L1 threads finished"
threadsL1_statusflag = True
def terminate(signum, frame):
print "\n------------------------------ Inside terminate()-------------------------\n\n"
stopThreadsL2()
stopThreadsL1()
sys.exit(1)
def main():
m_threads = []
signal.signal(signal.SIGINT, terminate)
signal.signal(signal.SIGTERM, terminate)
print "\n-----------------------Inside main thread------------------------\n"
startThreadL1_and_wait()
print "\n------------------------- All L1 threads started. Press Ctrl+C to stop !!------------------------\n"
joinThreadsL2()
if __name__ == '__main__':
main()
输出的
<pre>
reynold@heuristics:~/test$ python test_threading.py
-----------------------Inside main thread------------------------
Main() calling startThreadL1()
L1[T1] Inside startThreadL2
L1[T1] : Thread started
L2[T1]: Running
L2[T1] Thread started and appended to threads array
L2[T1]: Sleeping for 2 sec
L1[T2] Inside startThreadL2
L2[T2]: Running
L2[T2]: Sleeping for 2 sec
L2[T2] Thread started and appended to threads array
L1[T2] : Thread started
L1[%s] : Waiting for all threads to finish
L1[%s] : All L1 threads finished
------------------------- All L1 threads started. Press Ctrl+C to stop !!------------------------
L2 Inside joinThreadsL2()
L2[T2]: Sleeping for 2 sec
L2[T1]: Sleeping for 2 sec
L2[T2]: Sleeping for 2 sec
L2[T1]: Sleeping for 2 sec
L2[T2]: Sleeping for 2 sec
L2[T1]: Sleeping for 2 sec
^CL2[T2]: Sleeping for 2 sec
L2[T1]: Sleeping for 2 sec
^CL2[T2]: Sleeping for 2 sec
L2[T1]: Sleeping for 2 sec
^C^C^C^C^C^C^C^CL2[T2]: Sleeping for 2 sec
L2[T1]: Sleeping for 2 sec
^C^Z
[1]+ Stopped python test_threading.py
reynold@heuristics:~/test$ kill -9 %1
[1]+ Stopped python test_threading.py
reynold@heuristics:~/test$
</pre>
答案 0 :(得分:-1)
我在3.6中遇到了完全相同的问题,发现的解决方案是先在main中设置SIG_IGN,然后在创建线程之后,设置您自己的处理程序。
signal.signal(signal.SIGINT, signal.SIG_IGN)
signal.signal(signal.SIGTERM, signal.SIG_IGN)
worker.start()
signal.signal(signal.SIGINT, handler)
signal.signal(signal.SIGTERM, handler)
这确实是一个奇怪的问题,调用顶层类(直接继承线程)不会中断信号,但是任何较低层的类都需要解决方法。