浅析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中使用不同编码读写txt文件详解
May 28 Python
PHP网页抓取之抓取百度贴吧邮箱数据代码分享
Apr 13 Python
Python计算斗牛游戏概率算法实例分析
Sep 26 Python
Python使用matplotlib简单绘图示例
Feb 01 Python
Python常用字符串替换函数strip、replace及sub用法示例
May 21 Python
漂亮的Django Markdown富文本app插件的实现
Jan 02 Python
Python使用sqlalchemy模块连接数据库操作示例
Mar 13 Python
tensorflow查看ckpt各节点名称实例
Jan 21 Python
python模拟哔哩哔哩滑块登入验证的实现
Apr 24 Python
如何理解Python中的变量
Jun 01 Python
Python爬虫+Tkinter制作一个翻译软件的示例
Feb 20 Python
Python接口自动化系列之unittest结合ddt的使用教程详解
Feb 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
PHP字符转义相关函数小结(php下的转义字符串)
2007/04/12 PHP
利用static实现表格的颜色隔行显示的代码
2007/09/02 PHP
php file_exists 检查文件或目录是否存在的函数
2010/05/10 PHP
使用NetBeans + Xdebug调试PHP程序的方法
2011/04/12 PHP
php使用curl抓取qq空间的访客信息示例
2014/02/28 PHP
php解决和避免form表单重复提交的几种方法
2016/08/31 PHP
PHP 7.4中使用预加载的方法详解
2019/07/08 PHP
js关闭父窗口时关闭子窗口
2013/04/01 Javascript
使用jQuery快速解决input中placeholder值在ie中无法支持的问题
2014/01/02 Javascript
JS中获取函数调用链所有参数的方法
2015/05/07 Javascript
基于WebUploader的文件上传js插件
2016/08/19 Javascript
js原生跨域_用script标签的简单实现
2016/09/24 Javascript
微信小程序图片宽100%显示并且不变形
2017/06/21 Javascript
React Native 截屏组件的示例代码
2017/12/06 Javascript
Vue中的slot使用插槽分发内容的方法
2018/03/01 Javascript
mpvue 单文件页面配置详解
2018/12/02 Javascript
React精髓!一篇全概括小结(急速)
2019/05/23 Javascript
详解Vue+elementUI build打包部署后字体图标丢失问题
2020/07/13 Javascript
vue axios封装httpjs,接口公用配置拦截操作
2020/08/11 Javascript
Python实现命令行通讯录实例教程
2016/08/18 Python
python 调用win32pai 操作cmd的方法
2017/05/28 Python
彻底搞懂Python字符编码
2018/01/23 Python
matplotlib 纵坐标轴显示数据值的实例
2018/05/25 Python
python dlib人脸识别代码实例
2019/04/04 Python
Python threading的使用方法解析
2019/08/28 Python
Python字典的概念及常见应用实例详解
2019/10/30 Python
python中的RSA加密与解密实例解析
2019/11/18 Python
python3读取csv文件任意行列代码实例
2020/01/13 Python
Tensorflow 1.0之后模型文件、权重数值的读取方式
2020/02/12 Python
世界上最大的隐形眼镜商店:1-800 Contacts
2018/11/03 全球购物
俄罗斯苹果优质经销商商店:iPort
2020/05/27 全球购物
小学生关于梦想的演讲稿
2014/08/22 职场文书
企业整改报告范文
2014/11/08 职场文书
先进教师个人总结
2015/02/11 职场文书
2015年骨干教师工作总结
2015/05/26 职场文书
Python中npy和mat文件的保存与读取
2022/04/24 Python