python中的非阻塞使用互斥锁
鎖定方法acquire可以有一個blocking參數。
?
如果設定blocking為True,則當前線程會堵塞,直到獲取到這個鎖為止(如果沒有指定,那么默認為True)
?
如果設定blocking為False,則當前線程不會堵塞
?
from threading import Thread, Lock
import time
?
num =0? # 資源競爭問題
?
mutex= Lock()? # 創建一個互斥鎖
?
def fun1():
??? global num
??? for i in range(1000000):
??????? while True:
?????????? ?# mutex.acquire(blocking=False) # 通過blocking參數,如果設置為True表示acquire函數屬于阻塞方式,否則,非阻塞方法
??????????? result =mutex.acquire(False) ?# 通過blocking參數,如果設置為True表示acquire函數屬于阻塞方式,否則,非阻塞方法
??????????? # acquire返回值result的含義
???????? ???# 如果返回True,表示上鎖成功 (意思是,鎖原本處于未上鎖狀態,此次調用成功將鎖設置為上鎖狀態)
???????????# 如果返回False, 表示上鎖失敗 (意思是,鎖原本就屬于上鎖狀態,此次調用再想上鎖是不能完成)
??????????? if result:
??????????????? # result為True,表示成功上鎖,可以修改資源
??????????????? num += 1
??????????????? mutex.release()? # 釋放鎖,表示將鎖設置為打開狀態
??????????????? break
??????????? else:
??????????????? # result為False,表示沒有成功上鎖,所以嘗試下一次操作
??????????????? print("線程1 雖然沒有拿到鎖,但是可以唱歌")
??????????????? time.sleep(0.1)
?
?
def fun2():
??? global num
??? for i in range(1000000):
??????? while True:
??????????? result = mutex.acquire(False)
??????????? if result:
??????????????? num += 1
??????????????? mutex.release()? # 釋放鎖,表示將鎖設置為打開狀態
??????????????? break
??????????? else:
??????????????? print("線程2 雖然沒有拿到鎖,但是可以跳舞")
??????????????? time.sleep(0.1)
?
?
t1 =Thread(target=fun1)? # 創建一個線程對象
t2 =Thread(target=fun2)? # 創建一個線程對象
?
t1.start()? # 開啟線程的執行
t2.start()
?
t1.join()? # 回收線程資源
t2.join()
?
print(num)
?
上鎖解鎖過程
當一個線程調用鎖的acquire()方法獲得鎖時,鎖就進入“locked”狀態。
每次只有一個線程可以獲得鎖。如果此時另一個線程試圖獲得這個鎖,該線程就會變為“blocked”狀態,稱為“阻塞”,直到擁有鎖的線程調用鎖的release()方法釋放鎖之后,鎖進入“unlocked”狀態。
線程調度程序從處于同步阻塞狀態的線程中選擇一個來獲得鎖,并使得該線程進入運行(running)狀態。
?
鎖的好處:
?????????????
??????? 確保了某段關鍵代碼只能由一個線程從頭到尾完整地執行
?
鎖的壞處:
?
?阻止了多線程并發執行,包含鎖的某段代碼實際上只能以單線程模式執行,效率就大大地下降了
?
由于可以存在多個鎖,不同的線程持有不同的鎖,并試圖獲取對方持有的鎖時,可能會造成死鎖
?
總結
以上是生活随笔為你收集整理的python中的非阻塞使用互斥锁的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VMware中ubuntu虚拟机与win
- 下一篇: python中的死锁