【发布时间】: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