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

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

另一种解决方法就是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. 服务 Service 简单案例 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  2. 微信小程序wxss的background本地图片问题

    在web 或者webapp开发中我们习惯了直接饮用本地图片做背景,例如 .aaa { background: url('img/1.png'); } 但是这种引用方式在微信小程序中是无法使用的,控制台 ...

  3. 【机器学习算法-python实现】採样算法的简单实现

    1.背景     採样算法是机器学习中比較经常使用,也比較easy实现的(出去分层採样).经常使用的採样算法有下面几种(来自百度知道):     一.单纯随机抽样(simple random samp ...

  4. 虚拟机下CentOS7开启SSH连接

    在虚拟机(Vmware Workstation)下,安装了CentOS7,现在想通过SSH工具连接虚拟机中的CentOS7 1.  首先,要确保CentOS7安装了  openssh-server,在 ...

  5. android 异常:ScrollView can host only one direct child

    android 采用ScrollView布局时出现异常:ScrollView can host only one direct child. 主要是ScrollView内部只能有一个子元素,即不能并列 ...

  6. 【ShoppingPeeker】-基于Webkit内核的爬虫蜘蛛引擎 ShoppingWebCrawler的姊妹篇-可视化任务Web管理

    ShoppingPeeker 这个项目是蜘蛛项目的可视化任务站点. 项目github地址:ShoppingPeeker 开发语言:C# 开发工具:Visual Studio 2017 +.Net Co ...

  7. js事件探秘

    Javascript中的事件,可以和html交互. 事件流 IE&Opera:事件冒泡 其他浏览器: 事件捕获 事件冒泡:事件由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传 ...

  8. 微信支付(APP支付)-服务端开发(一)

    微信支付,首先需要注册一个商户平台公众账号,(网址:https://pay.weixin.qq.com/index.php/home/d_login) 目前微信支付的接入方式有四种方式:公众号支付,A ...

  9. NodeJs相关系列文章

    1.图片上传之FileAPI与NodeJs 2.NodeJs之调试 3.CentOS下使用NVM 4.NodeJs之进程守护 5.Ubuntu下使用nvm 6.NodeJs之pm2 7.NodeJs之 ...

  10. linux下安装Oracle时交换空间不足的解决方法

    摘:linux下安装Oracle时交换空间不足的解决方法 linux上安装Oracle时交换空间不足的解决办法 增加交换空间有两种方法: 严格的说,在系统安装完后只有一种方法可以增加swap,那就是本 ...