浅析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中的默认参数详解
Jun 24 Python
Python使用Mechanize模块编写爬虫的要点解析
Mar 31 Python
Python自动化测试Eclipse+Pydev 搭建开发环境
Aug 15 Python
一步步教你用Python实现2048小游戏
Jan 19 Python
python中的计时器timeit的使用方法
Oct 20 Python
python 实现提取某个索引中某个时间段的数据方法
Feb 01 Python
python命令 -u参数用法解析
Oct 24 Python
多个python文件调用logging模块报错误
Feb 12 Python
QT5 Designer 打不开的问题及解决方法
Aug 20 Python
python实现excel公式格式化的示例代码
Dec 23 Python
详解python使用金山词霸的翻译功能(调试工具断点的使用)
Jan 07 Python
python自动生成证件号的方法示例
Jan 14 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
smarty静态实验表明,网络上是错的~呵呵
2006/11/25 PHP
linux下实现定时执行php脚本
2015/02/13 PHP
Yii框架Session与Cookie使用方法示例
2019/10/14 PHP
JS控制表格隔行变色
2006/06/26 Javascript
基于jQuery的动态增删改查表格信息,可左键/右键提示(原创自Zjmainstay)
2012/07/31 Javascript
有关于eclipse配置spket需要注意的一些地方
2013/04/07 Javascript
基于mouseout和mouseover等类似事件的冒泡问题解决方法
2013/11/18 Javascript
js中document.write使用过程中的一点疑问解答
2014/03/20 Javascript
jQuery中fadeOut()方法用法实例
2014/12/24 Javascript
jquery实现textarea输入框限制字数的方法
2015/01/15 Javascript
第一章之初识Bootstrap
2016/04/25 Javascript
Bootstrap前端开发案例二
2016/06/17 Javascript
AngularJS基础 ng-paste 指令简单示例
2016/08/02 Javascript
jQuery日期范围选择器附源码下载
2017/05/23 jQuery
js判断节假日实例代码
2017/12/27 Javascript
JavaScript设计模式之调停者模式实例详解
2018/02/03 Javascript
node下使用UglifyJS压缩合并JS文件的方法
2018/03/07 Javascript
微信小程序实现同一页面取值的方法分析
2019/04/30 Javascript
详解Vue+elementUI build打包部署后字体图标丢失问题
2020/07/13 Javascript
[01:52]2014DOTA2西雅图邀请赛 V社开大会你不知道的小秘密
2014/07/08 DOTA
python编写Logistic逻辑回归
2020/12/30 Python
Python基于csv模块实现读取与写入csv数据的方法
2018/01/18 Python
在python3中pyqt5和mayavi不兼容问题的解决方法
2019/01/08 Python
Pandas透视表(pivot_table)详解
2019/07/22 Python
Django基于客户端下载文件实现方法
2020/04/21 Python
Python使用OpenPyXL处理Excel表格
2020/07/02 Python
django有哪些好处和优点
2020/09/01 Python
BOSE德国官网:尽探索之力,享音乐之极
2016/12/11 全球购物
EJB包括(SessionBean,EntityBean)说出他们的生命周期,及如何管理事务的
2015/07/24 面试题
2014年自我评价
2014/01/04 职场文书
土木建筑学生自我评价
2014/01/14 职场文书
高考备战决心书
2014/03/11 职场文书
技术入股合作协议书
2014/10/07 职场文书
质量整改通知单
2015/04/21 职场文书
道歉的话怎么说
2015/05/12 职场文书
悬疑名作《朋友游戏》动画无字ED宣传片 新角色公开
2022/04/13 日漫