线程化时在函数中发送变量不起作用 python

Sending variable in function doesn't work when threading python

目前正在尝试做一个空闲动画,它在空闲 = True 时不断更新角色,并试图将其主要保留在一个函数中以备后用。

但是,当我在函数外更新 idle = False 时,它​​并没有停止动画。

我遇到了线程,它似乎解决了一些问题。

import time
import threading
b = True
def test_func():
    global b
    while b:
        print '1'

threading.Thread(target=test_func).start()
b = False

这行得通,但函数接受诸如

之类的东西会更容易
def test_func(b):

并使用它代替大量全局变量。特别是当我将它用于多种用途时,让它只接受检查哪一个而不是检查更多行会很有帮助。尝试做时

import time
import threading
b = True
def test_func(b):
    while b:
        print '1'

threading.Thread(target=test_func(b)).start()
b = False

(b) 似乎使线程无法正常工作,因为它不断运行而不是在 b = False 时停止

(这是我的小测试代码,其中 b 表示是否继续更新的布尔值,打印“1”部分代替了字符更新。) (我也尝试过使用 lambda,因为我记得在其他情况下,当我需要传递这样的变量时,这是有用的,但我测试了它,但它不起作用)

当您编写 threading.Thread(target=test_func(b)).start() 时,该函数会在线程启动之前作为收集 Thread 参数的一部分被调用;此外,该函数获取变量的副本,而不是变量本身。

为了完成这样的工作,您需要解决两个问题:

  • 让它接受一个参数,但仍然是一个将被调用的函数

    这可以通过几种方式完成。可能最干净的方法是使 test_func 成为对象的一部分,这样您就可以将 b 传递给构造函数,然后将方法作为线程:

    threading.Thread(target=Worker(b).test_func).start()
    

    这通常是最好的,因为它为所有与线程相关的数据和函数提供了一个位置(它们都位于同一个对象中)。

    如果这太多了,如果你真的只有一个函数需要像这样调用,你可以使用 functools.partial 或闭包:

    threading.Thread(target=partial(test_func, b)).start()
    
  • 使用可以就地修改的可变值

    当你将一个布尔值传递给一个函数时,该函数实际上得到了一个副本。您需要使用一些可以就地更改的可变值(对象、列表等)。

    如果您对第一项使用对象,这可能是最简单的:

    w = Worker()
    threading.Thread(target=w.test_func).start()
    w.b = False
    

    否则,您可以创建 b 字典或列表或类似的,然后更改其中的特定条目:

    threading.Thread(target=partial(test_func, b)).start()
    b['active'] = False