如何中断/停止/结束悬挂多线程的Python程序
我有一个实现线程像这样的Python程序:如何中断/停止/结束悬挂多线程的Python程序
class Mythread(threading.Thread):
def __init__(self, name, q):
threading.Thread.__init__(self)
self.name = name
self.q = q
def run(self):
print "Starting %s..." % (self.name)
while True:
## Get data from queue
data = self.q.get()
## do_some_processing with data ###
process_data(data)
## Mark Queue item as done
self.q.task_done()
print "Exiting %s..." % (self.name)
def call_threaded_program():
##Setup the threads. Define threads,queue,locks
threads = []
q = Queue.Queue()
thread_count = n #some number
data_list = [] #some data list containing data
##Create Threads
for thread_id in range(1, thread_count+1):
thread_name = "Thread-" + str(thread_id)
thread = Mythread(thread_name,q)
thread.daemon = True
thread.start()
##Fill data in Queue
for data_item in data_list:
q.put(data_item)
try:
##Wait for queue to be exhausted and then exit main program
q.join()
except (KeyboardInterrupt, SystemExit) as e:
print "Interrupt Issued. Exiting Program with error state: %s"%(str(e))
exit(1)
的call_threaded_program()是从不同的程序调用。
我的代码在正常情况下工作。但是,如果在其中一个线程中发生错误/异常,程序就会卡住(因为队列连接无限阻塞)。我能够退出该计划的唯一方法是关闭终端本身。
线程退出时终止此程序的最佳方法是什么?有没有干净的(其实我会采取任何方式)这样做?我知道这个问题已经被无数次地问过了,但我仍然无法找到令人信服的答案。我真的很感激任何帮助。
编辑: 我试着删除队列中的连接和使用的全球出口标志为Is there any way to kill a Thread in Python? 建议。然而,现在的行为就是这么奇怪,我无法理解到底是怎么回事。
import threading
import Queue
import time
exit_flag = False
class Mythread (threading.Thread):
def __init__(self,name,q):
threading.Thread.__init__(self)
self.name = name
self.q = q
def run(self):
try:
# Start Thread
print "Starting %s...."%(self.name)
# Do Some Processing
while not exit_flag:
data = self.q.get()
print "%s processing %s"%(self.name,str(data))
self.q.task_done()
# Exit thread
print "Exiting %s..."%(self.name)
except Exception as e:
print "Exiting %s due to Error: %s"%(self.name,str(e))
def main():
global exit_flag
##Setup the threads. Define threads,queue,locks
threads = []
q = Queue.Queue()
thread_count = 20
data_list = range(1,50)
##Create Threads
for thread_id in range(1,thread_count+1):
thread_name = "Thread-" + str(thread_id)
thread = Mythread(thread_name,q)
thread.daemon = True
threads.append(thread)
thread.start()
##Fill data in Queue
for data_item in data_list:
q.put(data_item)
try:
##Wait for queue to be exhausted and then exit main program
while not q.empty():
pass
# Stop the threads
exit_flag = True
# Wait for threads to finish
print "Waiting for threads to finish..."
while threading.activeCount() > 1:
print "Active Threads:",threading.activeCount()
time.sleep(1)
pass
print "Finished Successfully"
except (KeyboardInterrupt, SystemExit) as e:
print "Interrupt Issued. Exiting Program with error state: %s"%(str(e))
if __name__ == '__main__':
main()
程序的输出是如下:
#Threads get started correctly
#The output also is getting processed but then towards the end, All i see are
Active Threads: 16
Active Threads: 16
Active Threads: 16...
然后程序只是挂起或保持上打印活动线程。但是,由于退出标志设置为True,所以线程的运行方法未被执行。所以我不知道如何保持这些线程或发生了什么。
编辑: 我发现了这个问题。在上面的代码中,线程的get方法被阻塞,因此无法退出。用超时的get方法取而代之。我对刚才的run方法,我改良下面
def run(self):
try:
#Start Thread
printing "Starting %s..."%(self.name)
#Do Some processing
while not exit_flag:
try:
data = self.q.get(True,self.timeout)
print "%s processing %s"%(self.name,str(data))
self.q.task_done()
except:
print "Queue Empty or Timeout Occurred. Try Again for %s"%(self.name)
# Exit thread
print "Exiting %s..."%(self.name)
except Exception as e:
print "Exiting %s due to Error: %s"%(self.name,str(e))
我在C.做到了一次基本上我有这样开始了其他的人,并让他们的轨道,即主要工序中的代码。存储PID并等待返回码。如果您在某个流程中出现错误,代码将会显示,然后您可以停止其他所有流程。希望这有助于
编辑:
对不起,我可以在我的答案,你是使用线程都忘记了。但我认为它仍然适用。您可以打包或修改线程以获取返回值,也可以使用多线程池库。
如果要强制所有线程退出时,进程退出,你在创建线程之前,可以设置线程的“守护进程”标志设置为True。
http://docs.python.org/2/library/threading.html#threading.Thread.daemon
我已经为该线程设置了“守护程序”标志。请参阅上面的代码。但那不是问题。问题是,主进程不会退出,因为它正在等待队列耗尽。然而,队列永远不会退出,因为线程死了(因此没有人使用队列中的项目)。所以,这导致程序被卡住了。但我想我已经想出了这个问题(请参阅编辑) – NRS
您好,我试过包装线程捕获异常,并使用全球出口标志停止线程。但现在的行为很奇怪,这超出了我的理解。请参阅上面的编辑 – NRS