假如,开了十个线程并且做同样的一件事,他们需要带着自己的数据进来,完成事情后带着自己的数据出去。如果是并发,同时进来,他们的数据就会混乱。

一般情况,我们加锁就可以了,一个人先进来,先加锁,另一个人过来看到加锁了,就在外面等,等里面的人出来,自己进去加锁,这样就不会出现数据混乱的问题。

另一种解决方法就是threading.local()来解决问题。

先看下面这个现象

from threading import Thread

ret = -1  # 先定义一个变量

def task(arg):  # 写个任务,加个参数
global ret # 声明ret全局变量
ret = arg # 每一个线程进来到要改这个变量
print(ret) # 每个线程来,改了ret,然后取ret的值 for i in range(10): # i是线程的值,0 1 2 3 4 5 6 7 8 9
t = Thread(target=task, args=(i,)) # 开10个线程
t.start()
# 打印结果 0 1 2 3 4 5 6 7 8 9

这个程序开了10个线程,每个线程都执行了更改ret的值并获取ret更改后的值,如果非常快,他们取到的值都不一样.

如果让他们睡两秒再执行

from threading import Thread
import time ret = -1 # 先定义一个变量 def task(arg): # 写个任务,加个参数
global ret # 声明ret全局变量
ret = arg # 每一个线程进来到要改这个变量
time.sleep(2)
print(ret) # 每个线程来,改了ret,然后取ret的值 for i in range(10): # i是线程的值,0 1 2 3 4 5 6 7 8 9
t = Thread(target=task, args=(i,)) # 开10个线程
t.start()
# 打印结果 9 9 9 9 9 9 9 9 9 9

打印结果全是9

那么解决这个问题我们可以用threading.local()方法

from threading import Thread
from threading import local
import time
# 这是一个特殊的对象
ret = local() # 先实例化一个对象 def task(arg): # 写个任务,加个参数
ret = arg # 每一个线程进来都给他开辟一个独立的空间 单纯的threading.local()的作用就是这个
time.sleep(2)
print(ret) # 每个线程来,改了ret,然后取ret的值 for i in range(10): # i是线程的值,0 1 2 3 4 5 6 7 8 9
t = Thread(target=task, args=(i,)) # 开10个线程
t.start()
# 打印结果 0 3 2 5 7 9 8 4 1 6
threading.local()的作用就是为每个线程开辟一个独立的空间进行数据存储。

接下来我们自定义local对象
from threading import get_ident,Thread
import time storage = {} def set(k,v): # 来给storage设置值
ident = get_ident() # get_ident()能获取唯一标识,是一组数字
if ident in storage:
storage[ident][k] = v
else:
storage[ident] = {k:v} def get(k): # 来取storage的值
ident = get_ident()
return storage[ident][k] def task(arg):
set('val',arg)
v = get('val')
print(v) for i in range(10):
t = Thread(target=task,args=(i,))
t.start()

多线程局部变量之threading.local()用法的更多相关文章

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

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

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

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

  3. 多线程多进程学习threading,queue线程安全队列,线程间数据状态读取。threading.local() threading.RLock()

    http://www.cnblogs.com/alex3714/articles/5230609.html python的多线程是通过上下文切换实现的,只能利用一核CPU,不适合CPU密集操作型任务, ...

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

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

  5. threading.local在flask中的用法

    一.介绍 threading.local的作用: 多个线程修改同一个数据,复制多份变量给每个线程用,为每个线程开辟一块空间进行数据的存储,而每块空间内的数据也不会错乱. 二.不使用threading. ...

  6. Threading.local

    在多线程环境下,每个线程都有自己的数据.一个线程使用自己的局部变量比使用全局变量好,因为局部变量只有线程自己能看见,不会影响其他线程,而全局变量的修改必须加锁. Threading.local可以创建 ...

  7. Python多线程1:threading

    threading模块提供了高级别的线程接口,基于低级别的_thread模块实现. 模块基本方法 该模块定了的方法例如以下: threading.active_count()         返回当前 ...

  8. 线程锁、threading.local(flask源码中用的到)、线程池、生产者消费者模型

    一.线程锁 线程安全,多线程操作时,内部会让所有线程排队处理.如:list/dict/Queue 线程不安全 + 人(锁) => 排队处理 1.RLock/Lock:一次放一个 a.创建10个线 ...

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

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

随机推荐

  1. 微信小程序无法获取UnionId的情况及处理

    问题背景:做了微信小程序,一切都还正常,但是最后体验版放出去时,却发现很多用户无法绑定用户,后台返回:参数非法.经过多方排查,发现是微信拿到的code请求返回的数据里没有UnionId,也就是接口返回 ...

  2. 【Spark】Spark-架构

    Spark-架构 Spark Master at spark://node-01:7077 spark clustermanager_百度搜索 看了之后不再迷糊-Spark多种运行模式 - 简书 Sp ...

  3. 病毒木马查杀实战第020篇:Ring3层主动防御之基本原理

    前言 假设说我们的计算机中安装有杀毒软件,那么当我们有意或无意地下载了一个恶意程序后.杀软一般都会弹出一个对话框提示我们,下载的程序非常可能是恶意程序,建议删除之类的.或者杀软就不提示.直接删除了:或 ...

  4. 免费网络视频监控软件cmsclient

    http://www.brickcom.com/products/DetailView.php?modelname=CMS-Client&series=CMS#product-support ...

  5. swagger搭建(基于springBoot)详解

    前后端分离后,api接口文档的维护就成了一个让人头疼的问题,api接口更新慢,或因开发工作量大,没时间整理文档,导致前后端分离后前端同学和后端同 学都纠结于文档的问题.而swagger的出现,不亚于一 ...

  6. 【PMP】项目的定义和特点

    1.定义 项目是为创建独特的产品.服务和成果而进行的的临时性工作. 2.特点 2.1 独特的产品.服务或成果 实现项目目标可能产生一个或多个可交付成果.例如:即便采用相同的材料或者相同的施工单位来建设 ...

  7. Vue中CSS模块化最佳实践

    Vue风格指南中介绍了单文件组件中的Style是必须要有作用域的,否则组件之间可能相互影响,造成难以调试. 在Vue Loader Scope CSS和Vue Loader CSS Modules两节 ...

  8. struts2:多业务方法的处理(动态调用,DMI)

    struts2支持调用指定Action类中某一个业务方法.如果没有指定,则调用execute方法. 1. 第一种实现方式,通过URL叹号参数 1.1 创建Action类,带多个方法 package c ...

  9. 物联网架构成长之路(5)-EMQ插件配置

    1. 前言 上一小结说了插件的创建,这一节主要怎么编写代码,以及具体流程之类的.2. 增加一句Hello World 修改 ./deps/emq_plugin_wunaozai/src/emq_plu ...

  10. Coding in Delphi(前4章翻译版本) (PDF)

      第四章翻译完成有一段时间了 写在前面的话       本次翻译纯属爱好,目的是提高对英文文档的理解和阅读能力,本文档大部分采用直 译的方式,而且保留了原来的英文.目的只是辅助大家理解,不喜勿喷.翻 ...