python线程本地意外值
Posted
技术标签:
【中文标题】python线程本地意外值【英文标题】:python threading local unexpected value 【发布时间】:2021-12-24 12:54:42 【问题描述】:为什么 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)
【问题讨论】:
线程本地附加到线程。其他线程中的更改不会影响主线程中的版本。而且新线程甚至看不到主线程中的x
。
@KlausD 也许我没有解释清楚,但是threadLocal.x = x
做了我想要的,为什么使用 getattr 无法获得价值?
也许我也不够清楚:因为它在那个线程中不存在。
getattr(threadLocal, 'x', x)
中的x
不会是函数参数中的本地函数吗? @克劳斯D。
【参考方案1】:
线程池 在工作项之间共享其工作线程。这意味着如果一个工作项在下一个工作项之前完成,那么两者都可以在同一个线程上运行,从而看到相同的线程局部变量。
这正是这里发生的情况:由于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 参数和线程本地。
【讨论】:
以上是关于python线程本地意外值的主要内容,如果未能解决你的问题,请参考以下文章
Python - 数组复制/分配,numpy的意外'=array [:]'行为
想要将 Slidervalue 设置为 UserDefault:线程 1:致命错误:在隐式展开可选值时意外发现 nil [重复]