简述:

threading.local是全局变量但是它的值却在当前调用它的线程当中

作用:

在threading module中,有一个非常特别的类local。一旦在主线程实例化了一个local,它会一直活在主线程中,并且又主线程启动的子线程调用这个local实例时,它的值将会保存在相应的子线程的字典中。可以为每个线程创建一块独立的空间,让他存放数据。

使用方式:

在使用threading.local()之前,先了解一下局部变量和全局变量。

import threading
import time def worker():
x = 0
for i in range(100):
time.sleep(0.0001)
x += 1
print(threading.current_thread(),x) for i in range(10):
threading.Thread(target=worker).start() 运行结果:
<Thread(Thread-2, started 123145372971008)> 100
<Thread(Thread-6, started 123145393991680)> 100
<Thread(Thread-1, started 123145367715840)> 100
<Thread(Thread-3, started 123145378226176)> 100
<Thread(Thread-5, started 123145388736512)> 100
<Thread(Thread-7, started 123145399246848)> 100
<Thread(Thread-4, started 123145383481344)> 100
<Thread(Thread-10, started 123145415012352)> 100
<Thread(Thread-8, started 123145404502016)> 100
<Thread(Thread-9, started 123145409757184)> 100

全局变量:

使用global:

import threading
import time x = 0
def worker():
global x
x = 0
for i in range(100):
time.sleep(0.0001)
x += 1
print(threading.current_thread(),x) for i in range(10):
threading.Thread(target=worker).start() 运行结果:
<Thread(Thread-2, started 123145483571200)> 888
<Thread(Thread-5, started 123145499336704)> 908
<Thread(Thread-3, started 123145488826368)> 930
<Thread(Thread-4, started 123145494081536)> 937
<Thread(Thread-1, started 123145478316032)> 941
<Thread(Thread-6, started 123145504591872)> 947
<Thread(Thread-7, started 123145509847040)> 949
<Thread(Thread-8, started 123145515102208)> 955
<Thread(Thread-9, started 123145520357376)> 962
<Thread(Thread-10, started 123145525612544)> 964

上面例子中当主线程中x是全局变量时,就变成了公共资源(也就是同一个对象),每个子线程互相干扰,最终导致错误的计算结果。

Python提供了 threading.local 类,将这个类实例化得到一个全局对象,但是不同的线程使用这个对象存储的数据其它线程不可见(本质上就是不同的线程使用这个对象时为其创建一个独立的字典)。

使用threading.local() :

import threading
import time # class A:
# def __init__(self,x):
# self.x = x
# a = A(0) a = threading.local()#全局对象 def worker():
a.x = 0
for i in range(100):
time.sleep(0.0001)
a.x += 1
print(threading.current_thread(),a.x) for i in range(10):
threading.Thread(target=worker).start() 运行结果:
<Thread(Thread-4, started 123145570172928)> 100
<Thread(Thread-6, started 123145580683264)> 100
<Thread(Thread-1, started 123145554407424)> 100
<Thread(Thread-2, started 123145559662592)> 100
<Thread(Thread-8, started 123145591193600)> 100
<Thread(Thread-5, started 123145575428096)> 100
<Thread(Thread-3, started 123145564917760)> 100
<Thread(Thread-7, started 123145585938432)> 100
<Thread(Thread-10, started 123145601703936)> 100
<Thread(Thread-9, started 123145596448768)> 100

每个子线程使用全局对象a,但每个线程定义的属性a.x是该线程独有的。

举一个错误的例子:,主线程中使用threading.local定义本地变量x,x在主线程中是独有的,子线程中就访问不到主线程的x的属性。

import threading

X='abc'
ctx=threading.local()
ctx.x=123 #主线程中定义x本地属性
print(ctx,type(ctx),ctx.x) def work():
print(X)
print(ctx)
print(ctx.x) #子线程访问不到
print('Good job') threading.Thread(target=work).start()
运行结果:
<_thread._local object at 0x10407bd00> <class '_thread._local'> 123
abc
<_thread._local object at 0x10407bd00>
Exception in thread Thread-1:
Traceback (most recent call last):
File "/Users/ihoney/Python/test_4.py", line 12, in work
print(ctx.x)
AttributeError: '_thread._local' object has no attribute 'x'

ctx全局对象对主线程和子线程都是可以使用的,主线程定义了属性x,但子线程在尝试访问属性x时,就相当于访问自己线程内的属性x,而自己线程并没有定义,就会抛出AttributeError异常:'_thread._local' object has no attribute 'x'。

python之threading.local的更多相关文章

  1. [Python 多线程] threading.local类 (六)

    在使用threading.local()之前,先了解一下局部变量和全局变量. 局部变量: import threading import time def worker(): x = 0 for i ...

  2. flask 源码专题(七):threading.local和高级

    1.python之threading.local 当每个线程在执行 val.num=1 ,在内部会为此线程开辟一个空间,来存储 num=1 val.num,找到此线程自己的内存地址去取自己存储 num ...

  3. 03 flask源码剖析之threading.local和高级

    03 threading.local和高级 目录 03 threading.local和高级 1.python之threading.local 2. 线程唯一标识 3. 自定义threading.lo ...

  4. Python - python3.7新增的contextvars vs Thread local(threading.local)

    总结 和threading.local()类似.Python3.7新增. thread.local(): 不同线程,同一个变量保存不同的值. contextvars: 不同上下文,同一个变量保存不同的 ...

  5. 网络编程 多线程/socketserver模块/ threading.local

    线程:进程中负责程序执行的执行单元. 多线程:在1个进程中存在多个线程. 进程只是用来把资源集中在一起,而线程才是cpu上的执行单位. 每个进程都会默认有一个控制线程也叫作主线程. 进程之间是竞争关系 ...

  6. Python 线程(threading)

    Python 的thread模块是比较底层的模块,Python的threading模块是对thread做了一些包装,可以更加方便的 被使用; 1. 使用threading 模块 # 示例一: 单线程执 ...

  7. threading.local的作用?

    threading.local()这个方法的特点用来保存一个全局变量,但是这个全局变量只有在当前线程才能访问,如果你在开发多线程应用的时候  需要每个线程保存一个单独的数据供当前线程操作,可以考虑使用 ...

  8. 锁丶threading.local丶线程池丶生产者消费者模型

    一丶锁 线程安全: 线程安全能够保证多个线程同时执行时程序依旧运行正确, 而且要保证对于共享的数据,可以由多个线程存取,但是同一时刻只能有一个线程进行存取. import threading v = ...

  9. Flask补充--threading.local对象

    目录 Local 局部变量 全局变量 使用threading.local() 自定义threading.local 函数版 面向对象版 通过setattr和getattr实现 每个对象有自己的存储空间 ...

随机推荐

  1. Linux 域名服务器配置

    cat /etc/redhat-release CentOS Linux release 7.0.1406 (Core) 使用BIND构建DNS服务器 1.BIND服务器安装 yum install ...

  2. ADO连接数据库【msado15.dll】

    Microsoft ActiveX Data Objects (ADO) 注册表查看ADO版本:HKEY_LOCAL_MACHINE\Software\Microsoft\DataAccess下有Ve ...

  3. 阿里巴巴Java开发规约插件-体验

    插件有哪些功能? 阿里技术公众号于今年的2月9日首次公布<阿里巴巴Java开发规约>,瞬间引起全民代码规范的热潮,上月底又发布了PDF的终极版,大家踊跃留言,期待配套的静态扫描工具开放出来 ...

  4. 南京IT企业环境之最深心得体会

    我是南京做嵌入式的. 之前搞过一年的PC平台Linux内核开发,Linux内核态的仅仅要不是非常复杂的BUG还是能修复的.一年的Linux用户态软件开发. 然后近期搞了两年ARM嵌入式开发. 做的CM ...

  5. MySQL<事务与存储过程>

    事务与存储过程 事务管理 事务的概念 谓的事务就是针对数据库的一组操作,它可以由一条或多条SQL语句组成,同一个事务的操作具备同步的特点,即事务中的语句要么都执行,要么都不执行. 事务的使用 开启事务 ...

  6. ZooKeeper(六)-- CAP和BASE理论、ZAB协议

    一.CAP理论和BASE理论 1.CAP理论 CAP理论,指的是在一个分布式系统中,不可能同时满足Consistency(一致性). Availability(可用性).Partition toler ...

  7. Linux hwclock 命令

    hwclock 即 Hardware Clock 硬件时钟,该命令用于查询或设置硬件时钟:硬件时钟是指主机板上的时钟设备,也就是通常可在 BIOS 画面设定的时钟:系统时钟是指 Kernel 中的时钟 ...

  8. 多线程的学习与GDI的学习

    今天又是一周的周五,感觉过的好快,我感觉不是期盼周末的到来,而是感觉现在已经习惯啦每天坐在这里敲代码,其实我是一个性格非常开朗的女生,现在不知道为什么感觉默默地坐在自己位置上面敲代码成为了我习以为常的 ...

  9. OpenGL开发环境简介

    基于OpenGL标准开发的应用程序运行时需有动态链接库OpenGL32.DLL.Glu32.DLL,这两个文件在安装Windows NT时已自动装载到C:\WINDOWS\SYSTEM32目录下(这里 ...

  10. win10下安装Oracle 11g 32位客户端遇到INS-13001环境不满足最低要求

    在以管理员身份运行setup.exe之后,出现了:[INS-13001]环境不满足最低要求,通过网上搜索之后找到了解决途径 首先,打开你的解压后的database文件夹,找到stage,然后cvu,找 ...