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
请注意,任何 额外操作可能足以解决计时问题:例如,包括 print
ing 参数和本地线程。
为什么 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
请注意,任何 额外操作可能足以解决计时问题:例如,包括 print
ing 参数和本地线程。