在使用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

  上面例子使用多线程,每个子线程完成不同的计算任务,x是局部变量。

每个子线程都要压栈,每个栈是独立的空间。每次压栈,局部变量x的作用域地址是不同的(线程独享),计算结果互不干扰。

全局变量:

使用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是全局变量但是它的值却在当前调用它的线程当中 作用: 在threading module中,有一个非常特别的类local.一旦在主线程实例化了一个local,它会 ...

  2. python多线程threading.Lock锁用法实例

    本文实例讲述了python多线程threading.Lock锁的用法实例,分享给大家供大家参考.具体分析如下: python的锁可以独立提取出来 mutex = threading.Lock() #锁 ...

  3. 再看python多线程------threading模块

    现在把关于多线程的能想到的需要注意的点记录一下: 关于threading模块: 1.关于 传参问题 如果调用的子线程函数需要传参,要在参数后面加一个“,”否则会抛参数异常的错误. 如下: for i ...

  4. Python多线程 - threading

    目录 1. GIL 2. API 3. 创建子线程 4. 线程同步 4.1. 有了GIL,是否还需要同步? 4.1.1. 死锁 4.1.2. 竞争条件 4.1.3. GIL去哪儿了 4.2. Lock ...

  5. python:threading.Thread类的使用详解

    Python Thread类表示在单独的控制线程中运行的活动.有两种方法可以指定这种活动: 1.给构造函数传递回调对象 mthread=threading.Thread(target=xxxx,arg ...

  6. [转]python 多线程threading简单分析

    多线程和多进程是什么自行google补脑 对于python 多线程的理解,我花了很长时间,搜索的大部份文章都不够通俗易懂.所以,这里力图用简单的例子,让你对多线程有个初步的认识. 单线程 在好些年前的 ...

  7. 多线程threading.local的作用及原理?

    1.示例代码 import time import threading v = threading.local() def func(arg): # 内部会为当前线程创建一个空间用于存储:phone= ...

  8. python多线程threading

    本文通过 4个example 介绍python中多线程package —— threading的常用用法, 包括调用多线程, 同步队列类Queue, Ctrl+c结束多线程. example1. 调用 ...

  9. python多线程安全local()

    import time import threading from threading import local class Foo(local): pass # 实例化(创建)对象 foo = Fo ...

随机推荐

  1. C#图片验证码绘制

    制作验证码.也可以画弧线之类..... //新建一个网站,在后台代码中引用一个using Stystem.Drawing的命名空间 Bitmap img = , ); //制作一个宽100,高50的画 ...

  2. SpringBoot 之Quartz的使用

    对于Quartz的使用,还是想说一句,SpringBoot真的很好用啊! 第一步:当然是引入依赖啦 <parent> <groupId>org.springframework. ...

  3. GIT 基础-基础命令

    环境 centos7 1.安装 #yum install git 2.创建本地仓库 ( 这里用 /www/git) 这里里有个隐藏的文件夹 ```.git``` 为git仓库的配置文件夹, 不可随意修 ...

  4. C#获取AD域中计算机和用户的信息

    如果你的计算机加入了某个AD域,则可以获取该域中所有的计算机和用户的信息. 所用程序集,需要.Net Framework 4. 添加程序集引用 System.DirectoryServices.Acc ...

  5. 【数据库】java链接jdbc 释放资源

    /* *   编写快速 入门的jdbc 程序 : *    *    1. 先导入 具体的驱动jar包 *    2. 编写一个类 , 写jdbc 的程序 *  *  具体的编写 java类的 代码的 ...

  6. Drupal网站报错:PDOException: in lock_may_be_available()

    Drupal网站报错: 原因: windows中mysql的服务停止了: 解决办法: 在服务中,启动mysql服务 启动后,刷新页面,问题完美解决

  7. 几种常用的bootstrap功能。

    ---恢复内容开始--- 我对于bootstrap定义与一种插件,他可以使我们的网页布局更加的炫酷,更加的整洁和合理.他的优点不多说,缺点一个就够我们头疼的,那就是需要记一些长长的英文名. 我为大家说 ...

  8. JDBC中处理事务,小Demo

    事务的四大特性(ACID):  原子性(Atomicity):事务中所有操作是不可再分割的原子单位.事务中所有操作要么全部执行成功,要么全部执行失败.  一致性(Consistency):事务执行 ...

  9. apm飞控飞行模式详解

    1.稳定模式Stabilize稳定模式是使用得最多的飞行模式,也是最基本的飞行模式,起飞和降落都应该使用此模式.此模式下,飞控会让飞行器保持稳定,是初学者进行一般飞行的首选,也是FPV第一视角飞行的最 ...

  10. Android dialog圆角显示及解决出现的黑色棱角

    最近在开发一个天气预报的app,看到一个比较不错友情提示,如下:                怎么样,看起来比原始的dialog好看吧.好了,做法也许有很多,我介绍下我的做法吧, 首先,我第一个想到 ...