Python多線程同步、互斥鎖、死鎖

GIL:全局解釋器鎖,每個線程在執行的過程都需要先獲取GIL,保證同一時刻只有一個線程而已執行代碼

線程釋放GIL鎖的情況:在IO操作等呃能會引起阻塞的system call之前,可以暫時釋放GIL

但在執行完畢後,必須重新獲取GIL, Python3中使用計時器(執行時間打到閥值後,當前線程釋放GIL)

python使用多線程是併發 可以使用多線程利用多核的CPU資源

cpu密集型:也成為計算密集型,任務的特點是要進行大量的計算,消耗cpu資源,比如計算圓周率、對視頻進行高清解碼等等

全靠cpu的運算能力 這個時候單線程快

io密集型:涉及到網絡、磁盤IO的任務都是IO密集型任務,這類任務的特點是CPU消耗很少,任務的大部分時間都在等待IO操作完成,因為 IO的速度遠遠低於CPU和內存的速度 這個時候多線程快。

那麼如何解決多線程共享全局變量數據錯誤的問題呢,引入鎖。

<code>import threading

a = 100


def func1():
global a
for i in range(1000000):
meta.acquire() # 上鎖

a += 1
meta.release() # 釋放鎖
print(a)


def func2():
global a
for i in range(1000000):
meta.acquire()
a += 1
meta.release()
print(a)


# 創建鎖
meta = threading.Lock()


t1 = threading.Thread(target=func1)
t2 = threading.Thread(target=func2)
t1.start()
t2.start()
t1.join()
t2.join()
print(a)
/<code>

至於鎖的原理在下方粗略的畫一張草圖以供參考

Python多線程同步、互斥鎖、死鎖

使用鎖讓每個線程有序的切換執行,不會出現數據混亂。

但是在使用鎖的時候要注意不要寫出死鎖代碼,附死鎖代碼參考,總結一句就是互相持有對方線程所需要的鎖,造成死鎖

<code>import threading

a = 100


def func1():
global a
for i in range(1000000):
meta_A.acquire() # 上鎖
meta_B.acquire() # 上多把鎖 產生了死鎖 看下面代碼
print('-------------1')
a += 1
meta_B.release()
meta_A.release() # 釋放鎖
print(a)


def func2():
global a
for i in range(1000000):
meta_B.acquire()
meta_A.acquire()
print('------------2')
a += 1
meta_A.release()
meta_B.release()
print(a)


# 創建鎖
meta_A = threading.Lock()
meta_B = threading.Lock()


t1 = threading.Thread(target=func1)
t2 = threading.Thread(target=func2)
t1.start()
t2.start()
/<code>


分享到:


相關文章: