4

我很难理解 Python 线程,特别是因为文档在某些时候明确告诉您 RTFS,而不是友好地包含相关信息。我承认我没有资格阅读线程模块。我见过很多非常简单的例子,但它们都使用全局变量,这很令人反感,让我想知道是否有人真的知道何时何地需要使用它们,而不是仅仅为了方便。

特别是,我想知道:

  • threading.Thread(target=x), 是x共享的还是私有的?每个线程都有自己的堆栈,还是所有线程同时使用相同的上下文?
  • 将可变变量传递给线程的首选方法是什么?不可变的显然已经通过了Thread(args=[],kwargs={}),这就是所有示例所涵盖的内容。如果它是全球性的,我将不得不捏着鼻子使用它,但似乎必须有更好的方法。我想我可以将所有内容包装在一个类中,然后将实例传入,但最好也指向常规变量。
  • 我什么时候需要 threading.local()?在x上面?
  • 正如许多示例所示,我是否必须对 Thread 进行子类化才能更新数据?

我习惯于 Win32 线程和 pthreads,它在文档中明确列出了与线程的不同用途共享和不共享的内容。这些都是相当低级的,如果可能的话,我想避免 _thread 是pythonic。

我不确定它是否相关,但我正在尝试使用 OpenMP 风格的线程来掌握它 - 使用队列和一些线程同时运行 for 循环。使用全局变量和锁很容易,但现在我想确定范围以更好地使用锁。

4

1 回答 1

3

在 threading.Thread(target=x) 中,x 是共享的还是私有的?

它是私人的。每个线程都有自己的私有调用x.

例如,这类似于递归(不管多线程)。如果x调用自身,则每次调用x都会获得自己的“私有”框架,以及自己的私有局部变量。

将可变变量传递给线程的首选方法是什么?我是否必须继承 Thread 才能更新数据?

我认为这个target论点是一个快速的捷径,有利于快速实验,但除此之外没什么。在不应该使用它的地方使用它会导致您在问题中描述的所有限制(以及您在考虑的可能解决方案中描述的黑客行为)。

大多数时候,你会想要子类化threading.Thread. 创建/管理线程的代码会将所有可变共享对象传递给您的线程类' __init__,并且它们应该将这些对象作为它们的属性,并在运行时(在它们的run方法内)访问它们。

我什么时候需要 threading.local()?

你很少这样做,所以你可能不会。

如果可能的话,我想避免 _thread 是 pythonic

毫无疑问,避免它。

于 2014-03-24T21:29:13.173 回答