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…

但願看客老爺打賞些買西瓜錢

支付寶

支付寶

微信

微信
相關文章
相關標籤/搜索