多線程局部變量之threading.local()用法

假如,開了十個線程而且作一樣的一件事,他們須要帶着本身的數據進來,完成事情後帶着本身的數據出去。若是是併發,同時進來,他們的數據就會混亂。併發

通常狀況,咱們加鎖就能夠了,一我的先進來,先加鎖,另外一我的過來看到加鎖了,就在外面等,等裏面的人出來,本身進去加鎖,這樣就不會出現數據混亂的問題。ide

另外一種解決方法就是threading.local()來解決問題。spa

先看下面這個現象線程

from threading import Thread

ret = -1  # 先定義一個變量


def task(arg):  # 寫個任務,加個參數
    global ret  # 聲明ret全局變量
    ret = arg  # 每個線程進來到要改這個變量
    print(ret)  # 每一個線程來,改了ret,而後取ret的值


for i in range(10):  # i是線程的值,0 1 2 3 4 5 6 7 8 9
    t = Thread(target=task, args=(i,))  # 開10個線程
    t.start()
# 打印結果 0 1 2 3 4 5 6 7 8 9

這個程序開了10個線程,每一個線程都執行了更改ret的值並獲取ret更改後的值,若是很是快,他們取到的值都不同.code

若是讓他們睡兩秒再執行對象

from threading import Thread
import time

ret = -1  # 先定義一個變量


def task(arg):  # 寫個任務,加個參數
    global ret  # 聲明ret全局變量
    ret = arg  # 每個線程進來到要改這個變量
    time.sleep(2)
    print(ret)  # 每一個線程來,改了ret,而後取ret的值


for i in range(10):  # i是線程的值,0 1 2 3 4 5 6 7 8 9
    t = Thread(target=task, args=(i,))  # 開10個線程
    t.start()
# 打印結果 9 9 9 9 9 9 9 9 9 9

打印結果全是9blog

那麼解決這個問題咱們能夠用threading.local()方法get

from threading import Thread
from threading import local
import time
# 這是一個特殊的對象
ret = local()  # 先實例化一個對象


def task(arg):  # 寫個任務,加個參數
    ret = arg  # 每個線程進來都給他開闢一個獨立的空間  單純的threading.local()的做用就是這個
    time.sleep(2)
    print(ret)  # 每一個線程來,改了ret,而後取ret的值


for i in range(10):  # i是線程的值,0 1 2 3 4 5 6 7 8 9
    t = Thread(target=task, args=(i,))  # 開10個線程
    t.start()
# 打印結果 0 3 2 5 7 9 8 4 1 6
threading.local()的做用就是爲每一個線程開闢一個獨立的空間進行數據存儲。

接下來咱們自定義local對象
from threading import get_ident,Thread
import time

storage = {}


def set(k,v):  # 來給storage設置值
    ident = get_ident()  # get_ident()能獲取惟一標識,是一組數字
    if ident in storage:
        storage[ident][k] = v
    else:
        storage[ident] = {k:v}


def get(k):  # 來取storage的值
    ident = get_ident()
    return storage[ident][k]


def task(arg):
    set('val',arg)
    v = get('val')
    print(v)


for i in range(10):
    t = Thread(target=task,args=(i,))
    t.start()
相關文章
相關標籤/搜索