Python线程中的自动线程局部变量是什么?
我对Python的线程处理有点困惑,尤其是文档里有些地方直接叫你去看其他地方的资料,而不是友好地提供相关信息。我承认我觉得自己不太能理解线程模块。我见过很多简单的例子,但它们都使用了全局变量,这让我觉得很不舒服,也让我怀疑到底什么时候需要用全局变量,而不是仅仅因为方便。
我特别想知道:
- 在
threading.Thread(target=x)
中,x
是共享的还是私有的?每个线程都有自己的栈吗,还是所有线程同时使用同一个上下文? - 把可变变量传给线程的最佳方式是什么?不可变的变量显然可以通过
Thread(args=[],kwargs={})
来传,这在所有例子中都有。如果是全局变量,我可能不得不勉强使用它,但我觉得应该有更好的方法。我想我可以把所有东西放在一个类里,然后只传这个实例进来,但如果能直接指向普通变量就更好了。 - 我什么时候需要使用
threading.local()
?在上面的x
中吗? - 我必须像很多例子那样去子类化Thread来更新数据吗?
我习惯于Win32线程和pthread,这些文档里明确说明了不同线程使用时哪些是共享的,哪些不是。那些都是比较底层的东西,我希望能避免使用_thread,以便更符合Python的风格。
我不确定这是否相关,但我正在尝试用OpenMP风格的线程处理,想搞明白怎么做——让一个for循环并发运行,使用队列和一些线程。用全局变量和锁的时候很简单,但现在我想明确作用域,以便更好地使用锁。
1 个回答
在 threading.Thread(target=x) 中,x 是共享的还是私有的?
它是私有的。每个线程都有自己独立的 x 调用。
这有点像递归,比如说(不管是不是多线程)。如果 x 调用自己,每次调用 x 时都会有自己独立的“私有”环境,里面有自己的局部变量。
传递可变变量给线程的最佳方式是什么?我需要继承 Thread 来更新数据吗?
我觉得 target
这个参数就像是一个快速的捷径,适合做一些简单的实验,但其他用途就不太合适了。在不该使用的地方用它,会导致你在问题中提到的那些限制(还有你考虑的那些解决方案中的一些小技巧)。
大多数情况下,你应该继承 threading.Thread
。创建和管理线程的代码会把所有可变的共享对象传递给你线程类的 __init__
方法,然后这些对象应该作为属性保存,并在运行时(在它们的 run
方法中)访问。
我什么时候需要使用 threading.local()?
你很少需要,所以可能根本不需要。
我想尽量避免使用 _thread,以保持 Python 的风格。
毫无疑问,尽量避免使用它。