日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

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

生活随笔

當(dāng)前位置: 首頁(yè) >

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

發(fā)布時(shí)間:2024/9/27 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python多线程同步与互斥_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-8import 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)象稱為“線程不安全”。

互斥鎖同步

上面的例子引出了多線程編程的最常見問(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),稱為“同步阻塞”(參見多線程的基本概念)。

直到擁有鎖的線程調(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)題。

總結(jié)

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

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