【问题标题】:ThreadPoolExecutor preserves Thread-Local Data between iterations?ThreadPoolExecutor 在迭代之间保留线程本地数据?
【发布时间】:2020-08-11 19:12:19
【问题描述】:

我注意到,如果我使用 ThreadPoolExecutor(max_workers=5) 运行一个函数 10 次,则在迭代之间维护线程本地数据,就像重复使用线程一样。我有以下非常基本的代码要测试:

import time
import uuid
import threading
import concurrent.futures

thread_data = threading.local()

def conc_func(i):
   if not hasattr(thread_data, 'x'):
      thread_data.x = uuid.uuid4()
      print('Setting Thread Data: ', end='')
   else:
      print('Reading Thread Data: ', end='')
   print(thread_data.x)
   time.sleep(1)

def conc_pool():
   with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
      _ = executor.map(conc_func, range(10))

if __name__ == '__main__':
   conc_pool()

如果我运行这段代码,我会得到以下输出

Setting Thread Data: e0101c90-1de7-4c5c-8358-05c6e5b5c89f
Setting Thread Data: 34d1c796-d9e0-4000-a560-2b0d0da47fb4
Setting Thread Data: 2a62e83e-0945-40d4-8af5-e5e77ee9531f
Setting Thread Data: b9bf8871-ea9d-4dca-88d2-c8916ff47e5d
Setting Thread Data: 961a7725-9ebb-4711-81c9-253ddc1c9c80
Reading Thread Data: e0101c90-1de7-4c5c-8358-05c6e5b5c89f
Reading Thread Data: 34d1c796-d9e0-4000-a560-2b0d0da47fb4
Reading Thread Data: 2a62e83e-0945-40d4-8af5-e5e77ee9531f
Reading Thread Data: b9bf8871-ea9d-4dca-88d2-c8916ff47e5d
Reading Thread Data: 961a7725-9ebb-4711-81c9-253ddc1c9c80

如您所见,只有 5 个唯一 UUID(与唯一工作人员的数量相同)。因为我分配了最多 5 个工作人员,但传递了一个包含 10 个元素的迭代,所以每个工作人员处理两次迭代。然而,令我惊讶的是 Thread-Local Data 实例在迭代之间共享,而我希望它在每次运行时都是 CLEAN。

有没有办法自动清理本地线程数据的实例,还是我们应该在迭代结束时自行清理?

【问题讨论】:

  • " 在迭代之间维护线程本地数据,就好像线程被重用一样。"是的,这正是正在发生的事情,这就是线程池的全部意义
  • @juanpa.arrivillaga 谢谢。现在确实有意义。

标签: python python-multithreading thread-local-storage


【解决方案1】:

线程池重用线程,这就是重点。任何线程本地数据都附加到线程。只要它还活着,它就会留在线程中,并且不会自行清理。您必须手动完成。

话虽如此,我的建议是完全避免线程本地存储。我还没有看到有必要并且您不能简单地将数据作为参数传递的情况。也许除非你已经处理了设计糟糕的代码。缺点是很难调试并且是硬依赖,例如如果您想切换到单线程异步代码,那么您将再次遇到问题,就像现在您重用线程而不是每次都产生一个新线程一样。

【讨论】:

  • 谢谢,所以基本上线程本地数据是一种可用于线程范围的全局变量。在这种情况下,不使用它们是有意义的。
  • @YakuzaUA exacfly.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 2014-12-14
  • 1970-01-01
相关资源
最近更新 更多