简述:

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

作用:

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

使用方式:

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

  1. import threading
  2. import time
  3.  
  4. def worker():
  5. x = 0
  6. for i in range(100):
  7. time.sleep(0.0001)
  8. x += 1
  9. print(threading.current_thread(),x)
  10.  
  11. for i in range(10):
  12. threading.Thread(target=worker).start()
  13.  
  14. 运行结果:
  15. <Thread(Thread-2, started 123145372971008)> 100
  16. <Thread(Thread-6, started 123145393991680)> 100
  17. <Thread(Thread-1, started 123145367715840)> 100
  18. <Thread(Thread-3, started 123145378226176)> 100
  19. <Thread(Thread-5, started 123145388736512)> 100
  20. <Thread(Thread-7, started 123145399246848)> 100
  21. <Thread(Thread-4, started 123145383481344)> 100
  22. <Thread(Thread-10, started 123145415012352)> 100
  23. <Thread(Thread-8, started 123145404502016)> 100
  24. <Thread(Thread-9, started 123145409757184)> 100

全局变量:

使用global:

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

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

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

使用threading.local() :

  1. import threading
  2. import time
  3.  
  4. # class A:
  5. # def __init__(self,x):
  6. # self.x = x
  7. # a = A(0)
  8.  
  9. a = threading.local()#全局对象
  10.  
  11. def worker():
  12. a.x = 0
  13. for i in range(100):
  14. time.sleep(0.0001)
  15. a.x += 1
  16. print(threading.current_thread(),a.x)
  17.  
  18. for i in range(10):
  19. threading.Thread(target=worker).start()
  20.  
  21. 运行结果:
  22. <Thread(Thread-4, started 123145570172928)> 100
  23. <Thread(Thread-6, started 123145580683264)> 100
  24. <Thread(Thread-1, started 123145554407424)> 100
  25. <Thread(Thread-2, started 123145559662592)> 100
  26. <Thread(Thread-8, started 123145591193600)> 100
  27. <Thread(Thread-5, started 123145575428096)> 100
  28. <Thread(Thread-3, started 123145564917760)> 100
  29. <Thread(Thread-7, started 123145585938432)> 100
  30. <Thread(Thread-10, started 123145601703936)> 100
  31. <Thread(Thread-9, started 123145596448768)> 100

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

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

  1. import threading
  2.  
  3. X='abc'
  4. ctx=threading.local()
  5. ctx.x=123 #主线程中定义x本地属性
  6. print(ctx,type(ctx),ctx.x)
  7.  
  8. def work():
  9. print(X)
  10. print(ctx)
  11. print(ctx.x) #子线程访问不到
  12. print('Good job')
  13.  
  14. threading.Thread(target=work).start()
  15. 运行结果:
  16. <_thread._local object at 0x10407bd00> <class '_thread._local'> 123
  17. abc
  18. <_thread._local object at 0x10407bd00>
  19. Exception in thread Thread-1:
  20. Traceback (most recent call last):
  21. File "/Users/ihoney/Python/test_4.py", line 12, in work
  22. print(ctx.x)
  23. 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. Ubuntu 13.04 安装 Oracle11gR2

    #step 1: groupadd -g 2000 dbauseradd -g 2000 -m -s /bin/bash -u 2000 griduseradd -g 2000 -m -s /bin/ ...

  2. 对ChemDraw Prime 16.0你了解多少

    ChemDraw Prime 16.0应用是化学智能绘图程序的行业领导者.除了创建符合出版标准的绘图,化学家们可以使用ChemDraw Prime软件预测性能,搜索数据库等来节省时间,提高数据的准确性 ...

  3. 做BS开发,你应该知道的一些东西

    界面和用户体验(Interface and User Experience) 知道各大浏览器执行Web标准的情况,保证你的站点在主要浏览器上都能正常运行.你至少要测试以下引擎:Gecko(用于Fire ...

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

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

  5. 编写高性能的jQuery代码

    jQuery Optimization 现在jQuery已经出现在很多项目中,然而许多同学忽略了他的性能问题以及代码质量问题, 下面是我对jQuery的一些性能方面的学习. 选择器 选择器是jQuer ...

  6. 创建ros的程序包--3

    创建ros的程序包(原创博文,转载请标明出处--周学伟http://www.cnblogs.com/zxouxuewei/) 1.一个catkin程序包由什么组成? 一个程序包要想称为catkin程序 ...

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

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

  8. linux命令之find和locate

    1.find / -name  log.xml   按照名字查找log.xml文件 2.locate log.xml     查找log.xml文件(效率高) 3.grep 'hive'  word. ...

  9. mysql show processlist 命令检查mysql lock

    processlist命令的输出结果显示了有哪些线程在运行,可以帮助识别出有问题的查询语句,两种方式使用这个命令. 1. 进入mysql/bin目录下输入mysqladmin processlist; ...

  10. AndroidのListView之滑动列表项(点击事件和滑动事件共存)

    这里正好在项目有这么一个bt的需求,如下图ListView的item可以响应点击事件也可以响应item的左右滑动事件,两个事件可以相互独立互不影响. 听说iphone的list选项就有这样bt的功能, ...