浅析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爬虫之使用urllib2组件抓取网页内容
Nov 04 Python
Python读取网页内容的方法
Jul 30 Python
Python装饰器基础详解
Mar 09 Python
python中利用队列asyncio.Queue进行通讯详解
Sep 10 Python
python中的随机函数小结
Jan 27 Python
python机器学习之随机森林(七)
Mar 26 Python
Python django使用多进程连接mysql错误的解决方法
Oct 08 Python
在Python函数中输入任意数量参数的实例
Jul 16 Python
DJANGO-URL反向解析REVERSE实例讲解
Oct 25 Python
pycharm显示远程图片的实现
Nov 04 Python
Python Celery多队列配置代码实例
Nov 22 Python
基于Python计算圆周率pi代码实例
Mar 25 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 smarty模版引擎中的缓存应用
2009/12/02 PHP
php实现仿写CodeIgniter的购物车类
2015/07/29 PHP
PHP时间函数使用详解
2019/03/21 PHP
Javascript在IE下设置innerHTML时出现未知的运行时错误的解决方法
2011/01/12 Javascript
IE6下focus与blur错乱的解决方案
2011/07/31 Javascript
用Mootools获得操作索引的两种方法分享
2011/12/12 Javascript
JavaScript阻止浏览器返回按钮的方法
2015/03/18 Javascript
jQuery实现图片渐入渐出切换展示效果
2015/08/15 Javascript
深入理解jQuery 事件处理
2016/06/14 Javascript
jqPlot jQuery绘图插件的使用
2016/06/18 Javascript
大型JavaScript应用程序架构设计模式
2016/06/29 Javascript
JS删除数组里的某个元素方法
2018/02/03 Javascript
JS中获取 DOM 元素的绝对位置实例详解
2018/04/23 Javascript
通过nodejs 服务器读取HTML文件渲染到页面的方法
2018/05/17 NodeJs
VUE-Table上绑定Input通过render实现双向绑定数据的示例
2018/08/27 Javascript
JS实现Cookie读、写、删除操作工具类示例
2018/08/28 Javascript
[47:04]LGD vs infamous Supermajor小组赛D组 BO3 第二场 6.3
2018/06/04 DOTA
[42:25]EG vs Spirit Supermajor 败者组 BO3 第二场 6.4
2018/06/05 DOTA
[01:12:08]LGD vs OG 2019国际邀请赛淘汰赛 胜者组 BO3 第一场 8.24
2019/09/10 DOTA
Python Django给admin添加Action的方法实例详解
2019/04/29 Python
Python 经典算法100及解析(小结)
2019/09/13 Python
Python MySQL 日期时间格式化作为参数的操作
2020/03/02 Python
Python任务自动化工具tox使用教程
2020/03/17 Python
Python 实现自动完成A4标签排版打印功能
2020/04/09 Python
python爬虫学习笔记之Beautifulsoup模块用法详解
2020/04/09 Python
python神经网络编程实现手写数字识别
2020/05/27 Python
Ubuntu 20.04安装Pycharm2020.2及锁定到任务栏的问题(小白级操作)
2020/10/29 Python
完美解决torch.cuda.is_available()一直返回False的玄学方法
2021/02/06 Python
Jones Bootmaker官网:优质靴子和鞋子在线
2020/11/30 全球购物
优秀干部获奖感言
2014/01/31 职场文书
护理助产毕业生的求职信
2014/03/02 职场文书
服装设计师求职信
2014/06/04 职场文书
学生上课说话检讨书
2014/10/25 职场文书
法学专业求职信范文
2015/03/19 职场文书
电影小兵张嘎观后感
2015/06/03 职场文书
SQL IDENTITY_INSERT作用案例详解
2021/08/23 MySQL