天天看點

python鎖簡單舉例

代碼通過系統調用,請求OS配置設定一個新的線程

python裡面:

thread與threading都可以用來建立管理線程,thread比較底層,threading是thread子產品的擴充,提供了很多線程同步功能,使用起來更加友善強大。

這個target 可以是函數或是類的方法

子線程執行完入口函數後, 就停止了。 (生命周期就在這個入口函數裡。)

#在執行到t1.start()時會啟動一個新線程, 這個線程和主線程同時執行。
print('main thread start.')
import threading
from time import sleep

def Thread_entry():
    print('child thread 1 , start')
    sleep(15)
    print('child thread 1, end')

t1 = threading.Thread(target=Thread_entry)  #執行個體化類Thread, 并指定線程執行的入口
t1.start() #啟動線程
sleep(10)
print('main thread end.')

輸出:
main thread start.
child thread 1 , start
main thread end.
child thread 1, end
           

threading.Thread隻是建立線程對象

start才是建立

join的作用 #主線程要等子線程結束 t1.join()

鎖舉例:如果這個例子不用鎖,很有可能兩個線程得到的餘額都是2000,然後都是在2000上操作,最後的餘額可能是2010或是1990

import threading
from time import sleep

zhifubao = {'lucy': 2000} #公共變量,lucy的支付寶有2000元
#線程調用公共變量,都線上程内維護一份copy,如果多個線程同時擷取到同一個公共變量并對其修改,會出錯。 
#調用Lock函數,傳回一個鎖對象。
zhifubao_lock = threading.Lock()

def thread1_didi_pay(account, amount):
    #如果是局部變量,多個線程不會将其搞混亂的。因為每個線程都 
    #在代碼通路共享對象之前加鎖,當有多個線程同時執行lock.acquired()時,隻有一個線程能成功的擷取鎖,然後繼續執行代碼,
    # 其他線程繼續等待,直到獲得鎖為止。 
    zhifubao_lock.acquire()
    print('t1, get balace from bank.')
    balance = zhifubao['lucy']
    zhifubao['lucy'] = balance - amount
    #通路完共享對象,釋放鎖
    #通路結束後,一定要調用lock對象的realese方法,進行解鎖操作。否則其它等待的線程将永遠等待下去,成為死線程。
    zhifubao_lock.release()

def thread1_yuebao_interst(account,amount):
    #通路共享對象前加鎖
    zhifubao_lock.acquire()
    print('t1, get balace from bank.')
    balance = zhifubao['lucy']
    zhifubao['lucy'] = balance + amount
    #釋放鎖
    zhifubao_lock.release()

#此時,并不關心哪個線程先調用。
t1 = threading.Thread(target=thread1_didi_pay,args=(zhifubao['lucy'],10))
t2 = threading.Thread(target=thread1_yuebao_interst,args=('zhifubao[lucy]',10))
t1.start()
t2.start()
t1.join()
t2.join()
print(zhifubao)