浅析Python多线程下的变量问题


Posted in Python onApril 28, 2015

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

但是局部变量也有问题,就是在函数调用的时候,传递起来很麻烦:

def process_student(name):
  std = Student(name)
  # std是局部变量,但是每个函数都要用它,因此必须传进去:
  do_task_1(std)
  do_task_2(std)

def do_task_1(std):
  do_subtask_1(std)
  do_subtask_2(std)

def do_task_2(std):
  do_subtask_2(std)
  do_subtask_2(std)

每个函数一层一层调用都这么传参数那还得了?用全局变量?也不行,因为每个线程处理不同的Student对象,不能共享。

如果用一个全局dict存放所有的Student对象,然后以thread自身作为key获得线程对应的Student对象如何?

global_dict = {}

def std_thread(name):
  std = Student(name)
  # 把std放到全局变量global_dict中:
  global_dict[threading.current_thread()] = std
  do_task_1()
  do_task_2()

def do_task_1():
  # 不传入std,而是根据当前线程查找:
  std = global_dict[threading.current_thread()]
  ...

def do_task_2():
  # 任何函数都可以查找出当前线程的std变量:
  std = global_dict[threading.current_thread()]
  ...

这种方式理论上是可行的,它最大的优点是消除了std对象在每层函数中的传递问题,但是,每个函数获取std的代码有点丑。

有没有更简单的方式?

ThreadLocal应运而生,不用查找dict,ThreadLocal帮你自动做这件事:

import threading

# 创建全局ThreadLocal对象:
local_school = threading.local()

def process_student():
  print 'Hello, %s (in %s)' % (local_school.student, threading.current_thread().name)

def process_thread(name):
  # 绑定ThreadLocal的student:
  local_school.student = name
  process_student()

t1 = threading.Thread(target= process_thread, args=('Alice',), name='Thread-A')
t2 = threading.Thread(target= process_thread, args=('Bob',), name='Thread-B')
t1.start()
t2.start()
t1.join()
t2.join()

执行结果:

Hello, Alice (in Thread-A)
Hello, Bob (in Thread-B)

全局变量local_school就是一个ThreadLocal对象,每个Thread对它都可以读写student属性,但互不影响。你可以把local_school看成全局变量,但每个属性如local_school.student都是线程的局部变量,可以任意读写而互不干扰,也不用管理锁的问题,ThreadLocal内部会处理。

可以理解为全局变量local_school是一个dict,不但可以用local_school.student,还可以绑定其他变量,如local_school.teacher等等。

ThreadLocal最常用的地方就是为每个线程绑定一个数据库连接,HTTP请求,用户身份信息等,这样一个线程的所有调用到的处理函数都可以非常方便地访问这些资源。

Python 相关文章推荐
python解析xml模块封装代码
Feb 07 Python
Python浅拷贝与深拷贝用法实例
May 09 Python
python获取一组数据里最大值max函数用法实例
May 26 Python
使用Python实现博客上进行自动翻页
Aug 23 Python
python远程连接服务器MySQL数据库
Jul 02 Python
ubuntu16.04制作vim和python3的开发环境
Sep 23 Python
在python中pandas的series合并方法
Nov 12 Python
python web自制框架之接受url传递过来的参数实例
Dec 17 Python
Python API len函数操作过程解析
Mar 05 Python
Python如何用wx模块创建文本编辑器
Jun 07 Python
详解Python爬虫爬取博客园问题列表所有的问题
Jan 18 Python
通过Python把学姐照片做成拼图游戏
Feb 15 Python
python实现向ppt文件里插入新幻灯片页面的方法
Apr 28 #Python
Python实现对PPT文件进行截图操作的方法
Apr 28 #Python
在Python下尝试多线程编程
Apr 28 #Python
Python输出PowerPoint(ppt)文件中全部文字信息的方法
Apr 28 #Python
python使用append合并两个数组的方法
Apr 28 #Python
python实现的简单文本类游戏实例
Apr 28 #Python
初步解析Python下的多进程编程
Apr 28 #Python
You might like
php下HTTP Response中的Chunked编码实现方法
2008/11/19 PHP
php gzip压缩输出的实现方法
2013/04/27 PHP
php实现有趣的人品测试程序实例
2015/06/08 PHP
PHP生成随机数的方法总结
2018/03/01 PHP
Yii2框架加载css和js文件的方法分析
2019/05/25 PHP
Jquery CheckBox全选方法代码附js checkbox全选反选代码
2010/06/09 Javascript
JavaScript代码复用模式实例分析
2012/12/02 Javascript
详解Bootstrap创建表单的三种格式(一)
2016/01/04 Javascript
点击按钮出现60秒倒计时的简单js代码(推荐)
2016/06/07 Javascript
url传递的参数值中包含&时,url自动截断问题的解决方法
2016/08/02 Javascript
Bootstrap modal使用及点击外部不消失的解决方法
2016/12/13 Javascript
微信小程序网络请求的封装与填坑之路
2017/04/01 Javascript
微信小程序 共用变量值的实现
2017/07/12 Javascript
bootstrap表格内容过长时用省略号表示的解决方法
2017/11/21 Javascript
Vue中Quill富文本编辑器的使用教程
2018/09/21 Javascript
使用 electron 实现类似新版 QQ 的登录界面效果(阴影、背景动画、窗体3D翻转)
2018/10/23 Javascript
JS温故而知新之变量提升和时间死区
2019/01/27 Javascript
javascript设计模式之迭代器模式
2020/01/30 Javascript
Jquery如何使用animation动画效果改变背景色的代码
2020/07/20 jQuery
Python使用新浪微博API发送微博的例子
2014/04/10 Python
python中二维阵列的变换实例
2014/10/09 Python
使用Python编写基于DHT协议的BT资源爬虫
2016/03/19 Python
shelve  用来持久化任意的Python对象实例代码
2016/10/12 Python
解决python3 urllib中urlopen报错的问题
2017/03/25 Python
python使用pil库实现图片合成实例代码
2018/01/20 Python
python随机取list中的元素方法
2018/04/08 Python
pandas DataFrame实现几列数据合并成为新的一列方法
2018/06/08 Python
python 实现从高分辨图像上抠取图像块
2020/01/02 Python
Auguste The Label官网:澳大利亚一家精品女装时尚品牌
2020/06/14 全球购物
主持人演讲稿范文
2013/12/28 职场文书
2014年高三毕业生自我评价
2014/01/11 职场文书
开朗女孩的自我评价
2014/02/10 职场文书
图书室标语
2014/06/21 职场文书
活动总结格式
2014/08/30 职场文书
win10+anaconda安装yolov5的方法及问题解决方案
2021/04/29 Python
SQL语句中JOIN的用法场景分析
2021/07/25 SQL Server