python threading.local 线程隔离

threading.local() 返回的是一个特殊的对象,它的状态是线程隔离的,每个线程的对value赋值,其实是在对不同的值进行赋值,你应该知道,python的对象里,属性值保存在字典中,显然,mylocal里保存了多份字典,区分他们的正是线程ID"

1. 输出结果是多少

先看一段代码

import threading

mylocal = threading.local()
mylocal.value = 0


def add_one(index):
    mylocal.value = index
    print(mylocal.value)

for i in range(1, 11):
    t = threading.Thread(target=add_one,args=(i,))
    t.start()

print(mylocal.value)

这段代码的最终输出结果是多少呢?如果你有一定的多线程编程经验,你应该会回答说结果不确定,因为mylocal.value的最终值是不确定的,10个线程对它进行写操作,只有最后那个执行的线程才会生效,实际的过程比这还要复杂

对内存中一个变量进行修改,可总结为三个步骤

  1. 将变量读取到寄存器中
  2. 在寄存器中修改
  3. 写回内存

哪个线程最后执行这第3步,哪个线程的执行是生效的, 你能理解到这一层次,已经非常好了,但是,这不是上面问题的答案

2. 线程隔离

实际执行上述代码的结果是0,threading.local() 返回的是一个特殊的对象,它的状态是线程隔离的,每个线程的对value赋值,其实是在对不同的值进行赋值,你应该知道,python的对象里,属性值保存在字典中,显然,mylocal里保存了多份字典,区分他们的正是线程ID

web框架flask,基于Werkzeug实现,而Werkzeug 自己封装了werkzeug.local.Local ,其效果和threading.local 基本一致,但也有一些不同,正是由于使用了这样的技术,所以App Context 对象和 Request Context 对象是请求间隔离的,也就是说,在多线程环境下,每个request对象都会准确的找到自己的信息

扫描关注, 与我技术互动

QQ交流群: 211426309

加入知识星球, 每天收获更多精彩内容

分享日常研究的python技术和遇到的问题及解决方案