如何正确停止Python线程?

4

我是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命令行提示符中时,我得到了以下结果。
如您所见,2个线程已经完成,但似乎程序没有退出(我没有收到命令提示符)。我认为这与我的代码有关,它没有正确结束线程。是这样吗?如何解决这个问题? 谢谢。

请查看我对问题“如何启动和停止线程”的回答(https://dev59.com/RmUo5IYBdhLWcg3w2CWJ#15734837)。 - martineau
据我所知,您只需要在主程序中调用 thread_1.join() - Joran Beasley
1
thread.setDaemon()已被弃用,请使用thread.daemon = True(或在创建线程时将其作为关键字参数传递)。请参阅文档:http://docs.python.org/2/library/threading.html#threading.Thread.daemon - ThinkChaos
2个回答

4

实际上,命令提示符在第>>> [DEBUG] (thread1 ) 2行返回,并准备接受更多的输入。守护线程在后台运行,打印出它们应该打印的内容,最终完成任务。你根本不需要输入ctrl-c。你可以直接输入另一个Python命令。


哇,确实就是这个问题!非常感谢你指出来。 - Just a learner

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
不完全是这样。线程没有标准的退出方式。你可以实现一些类似于事件的命令结构,但只有在线程编码时使用它才有效。另一个例子是队列和特殊消息,线程代码识别该消息以终止线程。 - tdelaney
不正确。除非目标线程定期检查stoprequest,或者被阻塞等待该特定事件,否则设置事件将不起作用。在Python中终止(非守护)线程的唯一可靠方法是由线程自身检测到停止的时间并停止。您可以使用threading.Event对象作为实现这一点的一种方式,但关键是线程需要合作。 - Evan
你说得完全正确,我的回答不够详细。我过去的经验是使用 while(threading_event.is_set()) - 因为线程无法被停止。当它的 run() 方法正常终止或引发未处理的异常时,它就不再存活了。 - actionseth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接