Python多線程(下)

前言

上節(jié)課我們分享了Python多線程的基礎(chǔ)語法,以及GIL的相關(guān)概念,這節(jié)課我們重點(diǎn)講解一個(gè)知識點(diǎn),就是多線程的數(shù)據(jù)安全問題。

數(shù)據(jù)安全問題

我們首先來舉一個(gè)例子,這里定義兩個(gè)函數(shù),一個(gè)是自加1,一個(gè)時(shí)自減1,按正常的邏輯來說,最后這個(gè)值應(yīng)該是0,但是程序每次運(yùn)行的結(jié)果都不一樣,有正數(shù),也有負(fù)數(shù)。

import threading

num = 0


def add():
    global num
    for i in range(10000000):
        num += 1


def sub():
    global num
    for i in range(10000000):
        num -= 1


t1 = threading.Thread(target=add)
t2 = threading.Thread(target=sub)
t1.start()
t2.start()
t1.join()
t2.join()
print(num)

這就是多線程的數(shù)據(jù)安全的問題,我簡單解釋一下,因?yàn)榫€程會在兩個(gè)函數(shù)中來回切換,好比在add函數(shù)中,剛準(zhǔn)備加1時(shí),程序被打斷,跳到了sub函數(shù)中繼續(xù)執(zhí)行,這就會導(dǎo)致num值的改變。

我們舉一個(gè)現(xiàn)實(shí)中的案例,很多人搶一張火車票,如果是多線程,當(dāng)一個(gè)人在搶票時(shí),突然切換到另外一個(gè)人買票,他買到了,然后又返回到第一個(gè)人,他這邊還是顯示的還有一張票,但其實(shí)后臺已經(jīng)沒票了。

這時(shí)我們就可以手動(dòng)加鎖來解決這樣的問題。

import threading

num = 0
lock = threading.Lock()


def add():
    lock.acquire()
    global num
    for i in range(10000000):
        num += 1
    lock.release()


def sub():
    lock.acquire()
    global num
    for i in range(10000000):
        num -= 1
    lock.release()


t1 = threading.Thread(target=add)
t2 = threading.Thread(target=sub)
t1.start()
t2.start()
t1.join()
t2.join()
print(num)

acquire函數(shù)就是申請鎖,release就是釋放鎖,這樣就能保證數(shù)據(jù)的安全。

今天的分享就到這了,我們下期再見~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容