我们在进行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 实现,甚至支持协程之间的私有数据,实现更加复杂,有机会再分析。

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

深入理解ThreadLocal变量的功能和使用相关推荐

  1. Python技术分享:深入理解ThreadLocal变量的功能和使用

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

  2. python中的thread_深入理解Python中的ThreadLocal变量(上)

    我们知道多线程环境下,每一个线程均可以使用所属进程的全局变量.如果一个线程对全局变量进行了修改,将会影响到其他所有的线程.为了避免多个线程同时对变量进行修改,引入了线程同步机制,通过互斥锁,条件变量或 ...

  3. [转]理解ThreadLocal

    ThreadLocal是什么 早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.使用这个工具类可以很简洁地 ...

  4. 通通透透理解ThreadLocal

    信息来源:网络 文章作者:未知 这篇文章有助于我们更好的理解ThreadLocal以及Spring对它的应用,例子都比较简单,动手尝试一下会加深理解. 我们知道Spring通过各种DAO模板类降低了开 ...

  5. 理解ThreadLocal 2

    为什么80%的码农都做不了架构师?>>>    摘自<Spring 揭密> 王福强著 人民邮电出版社 1 ThreadLocal的背景 单单从程序层面来看,我们编写的代码 ...

  6. 彻底理解ThreadLocal

    ynchronized这类线程同步的机制可以解决多线程并发问题,在这种解决方案下,多个线程访问到的,都是同一份变量的内容.为了防止在多线程访问的过程中,可能会出现的并发错误.不得不对多个线程的访问进行 ...

  7. 深入理解ThreadLocal

    学习JDK中的类,首先看下JDK API对此类的描述,描述如下: 该类提供了线程局部 (thread-local) 变量.这些变量不同于它们的普通对应物,因为访问某个变量(通过其 get 或 set ...

  8. Java并发编程--理解ThreadLocal

    另一篇博文:Hibernet中的ThreadLocal使用 http://www.cnblogs.com/gnivor/p/4440776.html 本文参考: http://blog.csdn.ne ...

  9. python中的常量可以修改吗_深入理解Python变量与常量

    变量是计算机内存中的一块区域,变量可以存储规定范围内的值,而且值可以改变.基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中.常量是一块只读的内存区域,常量一旦被初始化就不能被 ...

最新文章

  1. 六、线程的实现方式---多线程模型
  2. BZOJ.3004.[SDOI2012]吊灯(结论)
  3. 【任务脚本】0522更新京东618叠蛋糕任务脚本,京东任务自动程序
  4. 香帅的北大金融学课笔记11 -- 资产配置
  5. Scikit-learn 概述
  6. Linux系统下不同机器之间拷贝文件的方法
  7. 寫程式不需要天份,也不需要熱情
  8. (宏)Word 仅修改选中图片的尺寸
  9. C++编程语言中类的静态成员介绍
  10. 【ELK解决方案】ELK集群+RabbitMQ部署方案以及快速开发RabbitMQ生产者与消费者基础服务...
  11. 计算机毕业设计-SSM商场餐厅管理系统-JavaWeb商场餐厅管理系统
  12. ShowWindow的nCmdShow参数列表
  13. 2023年开网店还能赚钱吗?去哪里找货源?
  14. 迷人和漂亮的十几岁的明星
  15. 《淘宝网开店 拍摄 修图 设计 装修 实战150招》一一1.8 侧光拍摄增强轮廓感
  16. IEEE期刊/会议论文模板
  17. MongoDB--- 客户端操作 与 复制集
  18. 如何获取Html或Jsp中select框内的值(JS原生与非原生)
  19. 不知道密码,怎么打开PPT文件
  20. System.out.println()快捷键

热门文章

  1. java hasnextdouble_scanner.nextInt()与scanner.nextDouble
  2. java 继承对象 初始化_java中具有继承关系的类及其对象初始化顺序
  3. mysql重新创建测试对象的SQL_MySQL_Sql_打怪升级_进阶篇_测试: SQL随机生成测试数据...
  4. 《Python编程快速上手——让繁琐工作自动化》——2.5 控制流的元素
  5. 【微信开发】-- 企业转账到用户
  6. 多点子接口的帧中继配置
  7. 在VS.NET2003中使用XHTML的插件--HTML TIDY 及 MindManger
  8. [洛谷P2073] 送花
  9. 更新字典 (Updating a Dictionary,UVa12504)
  10. 微信sdk 隐藏右上角菜单项