2013-10-14 136 views
4

我是Python新手。这是我的代码:如何正确停止python线程?

import logging 
logging.basicConfig(level = logging.DEBUG, format = "[%(levelname)s] (%(threadName)-10s) %(message)s") 
import threading 
import time 

def thread1(): 
    for i in range(0, 10, 2): 
     logging.debug(i) 
     time.sleep(1) 


def thread2(): 
    for i in range(10, 20): 
     logging.debug(i) 
     time.sleep(1) 

t1 = threading.Thread(name = "thread1", target = thread1) 
t1.setDaemon(True) 
t1.start() 

t2 = threading.Thread(name = "thread2", target = thread2) 
t2.setDaemon(True) 
t2.start() 

当我复制的代码,并粘贴成一个Python的命令行提示符下,我得到了以下的结果。

enter image description here

正如你所看到的,2个线程已经完成,但似乎该程序不会退出(我没有得到命令提示符后面)。我认为它与我的代码没有属性结束线程有关。真的吗?如何解决这个问题? 谢谢。

+0

请参阅我的问题的回答[如何启动和停止线程](http://stackoverflow.com/questions/15729498/how-to-start-and-stop-thread/15734837 #15734837)。 – martineau

+0

afaik您只需要在您的主程序中调用'thread_1.join()' –

+1

thread.setDaemon()已被弃用,请使用thread.daemon = True(或在创建线程时将其作为关键字arg传递)。请参阅文档:http://docs.python.org/2/library/threading.html#threading.Thread.daemon – ThinkChaos

回答

4

实际上,命令提示符返回>>> [DEBUG] (thread1 ) 2行并准备好了更多的输入。 deamon线程在后台运行,打印出应有的内容并最终完成。你根本不需要输入ctrl-c。你可能刚刚输入了另一个python命令。

+0

WOW,这就是要点!非常感谢您指出这一点。 –

0

如果我没有记错 - 您需要使用threading.Event来停止线程。例如:

self.stoprequest = threading.Event() 

""" When self.stoprequest.set() is called, 
it sets an event on the thread - stopping it.""" 
self.stoprequest.set() 

因此,如果你创建每次启动线程上threading.Event(),您可以使用instance.set()

您也可以杀死主线程之外阻止它从哪个子线程催生:)

+1

不是。线程没有标准的退出方式。您可以实现某种类型的命令结构,如Event,但只有在线程已被编码才能使用时才有效。另一个例子是队列和线程代码识别终止的特殊消息。 – tdelaney

+0

不正确。除非目标线程定期检查stoprequest,否则阻塞在该特定事件上等待,设置事件不会执行任何操作。在python中终止一个(非守护进程)线程的唯一可靠方法是线程本身检测何时该停止并执行此操作。你可以使用'threading.Event'对象作为实现它的一种方式,但它们的关键在于线程需要合作。 – Evan

+0

你是对的,我的回答并不全面。我过去的经验是使用一段时间(threading_event.is_set()) - 因为线程无法停止。当run()方法终止时,它会停止活动 - 通常或者通过引发未处理的异常。 – actionseth