如何在另一个线程中结束 while 循环?

How to end a while loop in another Thread?

我想在 python 的另一个线程中结束 while True 循环:

from time import sleep
from threading import Thread

condition = False

def check_sth():
    while True:
        if condition:
            print("Condition met, ending")
            break
        else:
            sleep(0.25)
            do_sth()  # Do something everytime the condition is not met

Thread(target=check_sth(), args=(,)).start()
sleep(2)
condition = False
#  Doesn't print "Condition met..."

或者有没有一种方法可以简单地 kill 创建的线程,这样我就可以执行以下操作:

thread = Thread(target=check_sth(), args=(,))
thread.start()
thread.kill() # (?)

也欢迎使用 asyncio 或其他框架执行此操作的方法。

创建一个队列from Queue import Queue并将其传递给线程函数。在 while 循环中从队列中读取(使用 get)。代码的主体应该 put 队列中的某些内容将标记线程停止。

阅读更多here

您正在调用 check_sth 函数的结果并将其作为目标参数传递给 Thread。这就是您的代码不起作用的原因。这是你应该做的:

from time import sleep
from threading import Thread

condition = False

def check_sth():
    while True:
        if condition:
            print("Condition met, ending")
            break
        else:
            sleep(0.25)
            do_sth()  # Do something everytime the condition is not met

Thread(target=check_sth).start()
sleep(2)
condition = True

注意我用 check_sth 替换了 check_sth()。这样我传递的是实际函数,而不是它的结果。

is there a way to simply kill the...thread...?

让一个线程杀死另一个线程实际上从来都不是一个聪明的主意。原因很简单:线程通过改变共享程序变量的状态来相互通信。如果线程 A 在线程 B 之间没有任何形式的同步的情况下简单地杀死线程 B,那么线程 A 无法知道什么时候 安全时间 杀死线程 B,这样线程 B 将不要让事情处于 inconsistent/invalid 状态。

但是,另一方面,如果您同步它们,那么您就可以让线程 A 请求 线程 B 清理并终止自身。

同一个程序中的线程应该始终相互合作

请注意,您的代码在创建 Thread 时没有正确传递参数,并且永远不要将 condition 布尔变量设置为 True

以下是解决这些问题的方法 并且 能够停止另一个线程中的 while 循环。它不是简单的布尔变量,而是使用 Threading.Event 对象来控制循环并允许以线程安全的方式从主线程将其设置为真。

代码

from time import sleep
from threading import Event, Thread

condition = Event()

def do_sth():
    print("truckin' ...")

def check_sth():
    while not condition.is_set():
        sleep(0.25)
        do_sth()  # Do something everytime the condition is not set.

    print("Condition met, ending.")


Thread(target=check_sth, args=()).start()
sleep(2)
condition.set()  # End while loop.

输出

truckin' ...
truckin' ...
truckin' ...
truckin' ...
truckin' ...
truckin' ...
truckin' ...
truckin' ...
Condition met, ending.