我们在进行Python多线程开发的时候经常会使用到变量,但全局变量的变化影响到每一个线程,而局部变量使用起来又非常麻烦,所以我们需要使用到ThreadLocal变量,下面小千就来给大家介绍这个ThreadLocal变量到底是什么怎么用?

ThreadLocal变量它本身是一个全局变量,但是每个线程却可以利用它来保存属于自己的私有数据,这些私有数据对其他线程也是不可见的。下图给出了线程中这几种变量的存在情况

全局 VS 局部变量

首先借助一个小程序来看看多线程环境下全局变量的同步问题。

这里我们创建了10个线程,每个线程均对全局变量 global_num 进行1000次的加1操作(循环1000次加1是为了延长单个线程执行时间,使线程执行时被中断切换),当10个线程执行完毕时,全局变量的值是多少呢?

答案是不确定,简单来说是因为 global_num += 1 并不是一个原子操作,因此执行过程可能被其他线程中断,导致其他线程读到一个脏值。以两个线程执行 +1 为例,其中一个可能的执行序列如下(此情况下最后结果为1)

多线程中使用全局变量时普遍存在这个问题,解决办法也很简单,可以使用互斥锁、条件变量或者是读写锁。下面考虑用互斥锁来解决上面代码的问题,只需要在进行 +1 运算前加锁,运算完毕释放锁即可,这样就可以保证运算的原子性。

在线程中使用局部变量则不存在这个问题,因为每个线程的局部变量不能被其他线程访问。下面我们用10个线程分别对各自的局部变量进行1000次加1操作,每个线程结束时打印一共执行的操作次数(每个线程均为1000)

可以看出这里每个线程都有自己的 local_num,各个线程之间互不干涉。

Thread-local 对象

上面程序中我们需要给 show 函数传递 local_num 局部变量,并没有什么不妥。不过考虑在实际生产环境中,我们可能会调用很多函数,每个函数都需要很多局部变量,这时候用传递参数的方法会很不友好。

为了解决这个问题,一个直观的的方法就是建立一个全局字典,保存进程 ID 到该进程局部变量的映射关系,运行中的线程可以根据自己的 ID 来获取本身拥有的数据。这样,就可以避免在函数调用中传递参数,如下示例:

保存一个全局字典,然后将线程标识符作为key,相应线程的局部数据作为 value,这种做法并不完美。

首先,每个函数在需要线程局部数据时,都需要先取得自己的线程ID,略显繁琐。更糟糕的是,这里并没有真正做到线程之间数据的隔离,因为每个线程都可以读取到全局的字典,每个线程都可以对字典内容进行更改。

为了更好解决这个问题,python 线程库实现了 ThreadLocal 变量(很多语言都有类似的实现,比如Java)。ThreadLocal 真正做到了线程之间的数据隔离,并且使用时不需要手动获取自己的线程 ID,如下示例

上面示例中每个线程都可以通过 global_data.num 获得自己独有的数据,并且每个线程读取到的 global_data 都不同,真正做到线程之间的隔离。

ThreadLocal 实现的代码量不多,但是比较难理解,涉及很多 Python 黑魔法,下篇再来分析。那么 ThreadLocal 很完美了?不!Python 的 WSGI 工具库 werkzeug 中有一个更好的 ThreadLocal 实现,甚至支持协程之间的私有数据,实现更加复杂,有机会再分析。

本文来自千锋教育,转载请注明出处。

Python技术分享:深入理解ThreadLocal变量的功能和使用相关推荐

  1. 深入理解ThreadLocal变量的功能和使用

    我们在进行Python多线程开发的时候经常会使用到变量,但全局变量的变化影响到每一个线程,而局部变量使用起来又非常麻烦,所以我们需要使用到ThreadLocal变量,下面小千就来给大家介绍这个Thre ...

  2. python技术分享

    文章目录 python介绍 应用领域 环境搭建 基础知识 编程工具 变量 基本数据类型 容器数据类型 程序结构 运算符 函数 类 技巧总结 python内存管理 python常用技术 python的缺 ...

  3. Python技术分享:Python学习的一些小技巧

    "人生苦短,我选Python".那么,你真的掌握了Python吗?下面小千为大家介绍初学Python的17个学习小技巧! 1.交换变量 有时候,当我们要交换两个变量的值时,一种常规 ...

  4. 2022新年重磅技术分享|深入理解Linux操作系统

    hi 大家好,这里是极客重生,愿2021所有的遗憾都是2022惊喜的铺垫,前路浩浩荡荡,万事尽可期待,祝大家新的一年付出都有收获! 这次分享的主题是: 如何掌握和精通一门技术 如何学习和攻破操作系统 ...

  5. python实训英文_GitHub - MiracleYoung/You-are-Pythonista: 汇聚【Python应用】【Python实训】【Python技术分享】等等...

    You-are-Pythonista 汇聚[从零单排][实战项目][数据科学][自然语言处理][计算机视觉][面试题系列][大航海][Python应用][错题集][技术沙龙][内推渠道]等等 [人人都 ...

  6. pythonista脚本合集_GitHub - xchenhao/You-are-Pythonista: 汇聚【Python应用】【Python实训】【Python技术分享】等等...

    You-are-Pythonista 汇聚[从零单排][实战项目][Python面试题][大航海][Python应用][Python错题集][技术沙龙][内推渠道]等等 [人人都是Pythonista ...

  7. Python技术分享:ndarray对象的常用属性

    NumPy作为高性能科学计算和数据分析的基础包,是介绍其它重要数据分析工具的基础,掌握NumPy的功能及其用法,将有助于后续其他数据分析工具的学习. NumPy中最重要的一个特点就是其N维数组对象,即 ...

  8. Python技术分享:numpy库的安装教程

    一.numpy简介 NumPy是一个功能强大的Python库,主要用于对多维数组执行计算.NumPy这个词来源于两个单词-- Numerical和Python.NumPy提供了大量的库函数和操作,可以 ...

  9. python技术分享_分享几个python的使用技巧

    分享几个python的使用技巧 发布时间:2020-11-09 15:58:28 来源:亿速云 阅读:63 这篇文章将为大家详细讲解有关分享几个python的使用技巧,文章内容质量较高,因此小编分享给 ...

最新文章

  1. 为什么只有很少的人听说过西工大这个名字?
  2. 第一阶段站立会议08
  3. 【以太坊】搭建测试网络之ubuntu系统安装node.js
  4. 远程登录的机器不是域控制器的方法
  5. 框架页,URL中文参数乱码
  6. 盖茨推荐人人该读的九本书
  7. c# AseConnection的类型初始值设定项引发异常 无法加载 DLL sybdrvado11.dll 解决办法...
  8. 使用实例_EM菌使用实例
  9. php 易语言md5加密解密,详解易语言调用js实现md5加密方法
  10. mysql 授权访问_windows开启3306端口并用可视化工具访问远程mysql(授权访问)
  11. 前端学习(1906)vue之电商管理系统电商系统之渲染修改用户的表单
  12. 比较标签 php,比较标签 · ThinkPHP5.0完全开发手册 · 看云
  13. 由 Apache 说开,中国开源项目已经走向世界!
  14. 数据结构+算法+c++学习(写在前面)
  15. 银行考试打字测试软件,银行考核打字,是否有什么练习软件?
  16. 《计算机系统基础》4-6章 简答题
  17. 现代密码学常用符号总结
  18. 正则表达式行尾行首添加字符
  19. 南阳ACM 题目722 数独
  20. 常见几个排序源码及二分查找源码

热门文章

  1. feign直接走熔断_四、Spring Cloud之熔断处理 Hystrix
  2. Base64编码运用与基本原理
  3. 《Java程序设计》实验报告——Java的对象与类
  4. 欧拉函数(Euler_Function)
  5. 维沃手机有没有智能机器人_权威发布!2019世界智能移动终端产业高峰会议获奖名单...
  6. Maven-学习笔记06【基础-Maven工程servlet实例】
  7. Redis-学习笔记01【Redis环境搭建】
  8. Java原子操作Atomic
  9. Java线程安全Lock、ReentrantLock、ReentrantReadWriteLock
  10. Android 5中不同效果的Toast