Python多线程学习(三)

ThreadLocal

在多线程状况下,每一个线程的局部变量只有本身能看到,线程之间不会影响,可是局部变量在函数调用的时候传递很麻烦。php

案例:ios

def myfunc(name):
    std = Student(name)
    # std是局部变量,可是每一个函数都要用它,所以必须传进去:
    do_task_1(std)
    do_task_2(std)

def t1(std):
    t2(std)
    t3(std)
    
def t2(std):
    t4(std)
    t5(std)
复制代码

每一个函数一层一层调用都按照这种方式传参很繁琐冗余。用全局变量也不行,由于每一个线程处理不一样的 Student 对象,没法共享。数据库

能够想到用一个全局变量 dict 存放全部的 Student 对象,而后以 thread 自身做为 key 得到线程对应的 Student 对象。微信

实战( Python3 )多线程

d = {}

def std_thread(name):
    std = Student(name)
    # 把 std 放到全局变量 d 中:
    d[threading.current_thread()] = std
    t1()
    t2()
    
def t1():
    # 不传入 std ,而是根据当前线程查找:
    std = d[threading.current_thread()]
    ...
    
def t2():
    # 任何函数均可以查找出当前线程的std变量:
    std = d[threading.current_thread()]
    ...
复制代码

这种方式最大的优势是消除了 std 对象在每层函数中的传递问题,代码有点丑。在这种状况下 ThreadLocal 应运而生,不用查找 dictThreadLocal 帮你自动作这件事。yii

实战( Python3 )svg

import threading
    
# 建立全局 ThreadLocal 对象:
tl = threading.local()
def process():
    # 获取当前线程关联的 student:
    name = tl.student
    print('Hello, %s (in %s)' % (name, threading.current_thread().name))
    
def task(name):
    # 绑定 ThreadLocal 的 student :
    tl.student = name
    process()
    
t1 = threading.Thread(target= task, args=('sam',), name='t1')
t2 = threading.Thread(target= task, args=('echo',), name='t2')
t1.start()
t2.start()
t1.join()
t2.join()   
复制代码

运行结果:函数

Hello, sam (in t1)
Hello, echo (in t2)
复制代码
  • ThreadLocal 最经常使用的地方就是为每一个线程绑定一个数据库链接,HTTP 请求,用户身份信息等,这样一个线程的全部调用到的处理函数均可以很是方便地访问这些资源。ui

  • 一个 ThreadLocal 变量虽然是全局变量,但每一个线程都只能读写本身线程的独立副本,互不干扰也不用管理锁的问题,ThreadLocal 内部会处理。。ThreadLocal 解决了参数在一个线程中各个函数之间互相传递的问题。es5

本文参考:

廖雪峰:www.liaoxuefeng.com/wiki/101695…

但愿看客老爷打赏些买西瓜钱

支付宝

支付宝

微信

微信
相关文章
相关标签/搜索