浅析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中的25个隐藏特性
Mar 30 Python
详解Python中time()方法的使用的教程
May 22 Python
python中set()函数简介及实例解析
Jan 09 Python
使用Python读取二进制文件的实例讲解
Jul 09 Python
对numpy中向量式三目运算符详解
Oct 31 Python
Python中安装easy_install的方法
Nov 18 Python
python关于矩阵重复赋值覆盖问题的解决方法
Jul 19 Python
python线程信号量semaphore使用解析
Nov 30 Python
解析PyCharm Python运行权限问题
Jan 08 Python
用Python实现童年贪吃蛇小游戏功能的实例代码
Dec 07 Python
python绘制箱型图
Apr 27 Python
Python初学者必备的文件读写指南
Jun 23 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
Mysql的Root密码忘记,查看或修改的解决方法(图文介绍)
2013/06/14 PHP
php实现邮件发送并带有附件
2014/01/24 PHP
php面向对象编程self和static的区别
2016/05/08 PHP
php利用header函数下载各种文件
2016/08/24 PHP
ThinkPHP实现转换数据库查询结果数据到对应类型的方法
2017/11/16 PHP
javascript脚本调试方法小结
2008/11/24 Javascript
表单切换,用回车键替换Tab健(不支持IE)
2011/07/20 Javascript
解决jquery操作checkbox火狐下第二次无法勾选问题
2014/02/10 Javascript
使用jquery操作session方法分享
2015/01/22 Javascript
javascript中返回顶部按钮的实现
2015/05/05 Javascript
对JavaScript的全文搜索实现相关度评分的功能的方法
2015/06/24 Javascript
JavaScript实现图片轮播的方法
2015/07/31 Javascript
js原型链与继承解析(初体验)
2016/05/09 Javascript
js防刷新的倒计时代码 js倒计时代码
2017/09/06 Javascript
pace.js和NProgress.js两个加载进度插件的一点小总结
2018/01/31 Javascript
用jQuery将JavaScript对象转换为querystring查询字符串的方法
2018/11/12 jQuery
微信小程序左滑删除功能开发案例详解
2018/11/12 Javascript
vue-week-picker实现支持按周切换的日历
2019/06/26 Javascript
jQuery实现消息弹出框效果
2019/12/10 jQuery
JavaScript中CreateTextFile函数
2020/08/30 Javascript
解决Vue大括号字符换行踩的坑
2020/11/09 Javascript
Python中for循环详解
2014/01/17 Python
Python循环语句中else的用法总结
2016/09/11 Python
Python实现桶排序与快速排序算法结合应用示例
2017/11/22 Python
Pycharm在创建py文件时,自动添加文件头注释的实例
2018/05/07 Python
Django unittest 设置跳过某些case的方法
2018/12/26 Python
django使用admin站点上传图片的实例
2019/07/28 Python
Python 操作 PostgreSQL 数据库示例【连接、增删改查等】
2020/04/21 Python
Expedia意大利旅游网站:酒店、机票和租车预订
2017/10/30 全球购物
美国机场停车位预订:About Airport Parking
2018/03/26 全球购物
吉列剃须刀英国官网:Gillette英国
2019/03/28 全球购物
巴西电子、家电、智能手机购物网站:Girafa
2019/06/04 全球购物
《一株紫丁香》教学反思
2014/02/19 职场文书
法制宣传实施方案
2014/03/13 职场文书
药品营销策划方案
2014/06/15 职场文书
班主任与学生安全责任书
2014/07/25 职场文书