日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

python多线程编程(3): 使用互斥锁同步线程

發(fā)布時(shí)間:2023/12/2 python 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python多线程编程(3): 使用互斥锁同步线程 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

問(wèn)題的提出

上一節(jié)的例子中,每個(gè)線程互相獨(dú)立,相互之間沒(méi)有任何關(guān)系。現(xiàn)在假設(shè)這樣一個(gè)例子:有一個(gè)全局的計(jì)數(shù)num,每個(gè)線程獲取這個(gè)全局的計(jì)數(shù),根據(jù)num進(jìn)行一些處理,然后將num加1。很容易寫出這樣的代碼:

# encoding: UTF-8
import threading
import time

class MyThread(threading.Thread):
def run(self):
global num
time.sleep(1)
num = num+1
msg = self.name+' set num to '+str(num)
print(msg)
num = 0
def test():
for i in range(5):
t = MyThread()
t.start()
if __name__ == '__main__':
test()

但是運(yùn)行結(jié)果是不正確的:

Thread-5 set num to 2
Thread-3 set num to 3
Thread-2 set num to 5
Thread-1 set num to 5
Thread-4 set num to 4

問(wèn)題產(chǎn)生的原因就是沒(méi)有控制多個(gè)線程對(duì)同一資源的訪問(wèn),對(duì)數(shù)據(jù)造成破壞,使得線程運(yùn)行的結(jié)果不可預(yù)期。這種現(xiàn)象稱為“線程不安全”。

互斥鎖同步

上面的例子引出了多線程編程的最常見(jiàn)問(wèn)題:數(shù)據(jù)共享。當(dāng)多個(gè)線程都修改某一個(gè)共享數(shù)據(jù)的時(shí)候,需要進(jìn)行同步控制。

線程同步能夠保證多個(gè)線程安全訪問(wèn)競(jìng)爭(zhēng)資源,最簡(jiǎn)單的同步機(jī)制是引入互斥鎖。互斥鎖為資源引入一個(gè)狀態(tài):鎖定/非鎖定。某個(gè)線程要更改共享數(shù)據(jù)時(shí),先將其鎖定,此時(shí)資源的狀態(tài)為“鎖定”,其他線程不能更改;直到該線程釋放資源,將資源的狀態(tài)變成“非鎖定”,其他的線程才能再次鎖定該資源。互斥鎖保證了每次只有一個(gè)線程進(jìn)行寫入操作,從而保證了多線程情況下數(shù)據(jù)的正確性。

threading模塊中定義了Lock類,可以方便的處理鎖定:

#創(chuàng)建鎖
mutex = threading.Lock()
#鎖定
mutex.acquire([timeout])
#釋放
mutex.release()

其中,鎖定方法acquire可以有一個(gè)超時(shí)時(shí)間的可選參數(shù)timeout。如果設(shè)定了timeout,則在超時(shí)后通過(guò)返回值可以判斷是否得到了鎖,從而可以進(jìn)行一些其他的處理。

使用互斥鎖實(shí)現(xiàn)上面的例子的代碼如下:

import threading
import time

class MyThread(threading.Thread):
def run(self):
global num
time.sleep(1)

if mutex.acquire(1):
num = num+1
msg = self.name+' set num to '+str(num)
print(msg)
mutex.release()
num = 0
mutex = threading.Lock()
def test():
for i in range(5):
t = MyThread()
t.start()
if __name__ == '__main__':
test()

運(yùn)行結(jié)果:

Thread-3 set num to 1
Thread-4 set num to 2
Thread-5 set num to 3
Thread-2 set num to 4
Thread-1 set num to 5

可以看到,加入互斥鎖后,運(yùn)行結(jié)果與預(yù)期相符。

同步阻塞

當(dāng)一個(gè)線程調(diào)用鎖的acquire()方法獲得鎖時(shí),鎖就進(jìn)入“l(fā)ocked”狀態(tài)。每次只有一個(gè)線程可以獲得鎖。如果此時(shí)另一個(gè)線程試圖獲得這個(gè)鎖,該線程就會(huì)變?yōu)椤癰locked”狀態(tài),稱為“同步阻塞”(參見(jiàn)多線程的基本概念)。

直到擁有鎖的線程調(diào)用鎖的release()方法釋放鎖之后,鎖進(jìn)入“unlocked”狀態(tài)。線程調(diào)度程序從處于同步阻塞狀態(tài)的線程中選擇一個(gè)來(lái)獲得鎖,并使得該線程進(jìn)入運(yùn)行(running)狀態(tài)。

?

互斥鎖最基本的內(nèi)容就是這些,下一節(jié)將討論可重入鎖(RLock)和死鎖問(wèn)題。

轉(zhuǎn)載于:https://www.cnblogs.com/nuomin/p/7899592.html

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的python多线程编程(3): 使用互斥锁同步线程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。