python 线程本地异常值

python threading local unexpected value

为什么 getattr 不起作用?我不是要为 threadLocal 设置默认值,我想知道为什么 getattr 不能按我想要的方式工作?试图锁定,相同的输出

预期输出

0
1
2
3
4
main thread

当前输出

0
0
0
0
0
main thread

代码

from concurrent.futures import ThreadPoolExecutor
from threading import local

threadLocal = local()
threadLocal.x = 'main thread'

def f(x):
    # threadLocal.x = x # this works
    threadLocal.x = getattr(threadLocal, 'x', x) # this does not work
    return threadLocal.x

pool = ThreadPoolExecutor(5)
result = pool.map(f, range(0, 5))
for i in result:
    print(i)

print(threadLocal.x)

线程 在工作项之间共享其工作线程。这意味着如果一个工作项在下一个工作项之前完成,两者都可以 运行 在同一个线程上,因此看到相同的线程局部变量。

这正是这里发生的情况:由于 f 执行起来非常快,因此第一个工作线程中的大部分或所有工作项 运行。第一个任务 f(0) 在这里设置 threadLocal.x = 0,其他任务 运行 在同一线程 中读取 threadLocal.x = 0.

您可以通过(人为地)增加 f 的 运行 时间来规避此问题。

def f(x):
    time.sleep(0.2)  # delay for other work items to start running
    threadLocal.x = getattr(threadLocal, 'x', x) # this works now
    return threadLocal.x

请注意,任何 额外操作可能足以解决计时问题:例如,包括 printing 参数和本地线程。