【同步互斥】
1.同步互斥機制
-
目的:
解決對共有資源操作產生的爭奪 -
臨界資源:
多個進程或線程都能夠操作的資源(例如終端) -
臨界區:
操作臨界資源的代碼段 -
同步:
同步是一種合作關係,爲完成某個任務多進程和多線程之間形成一種協調,
按照約定或條件依次執行操作臨界資源,相互告知資源使用情況。
(這種協調可能是因爲阻塞關係達成的) -
互斥:
互斥是一種制約關係,當一個進程或者線程進入臨界區會進行加鎖的操作。
此時其他進程(線程)再企圖使用臨界資源時就會阻塞,直到資源被釋放才能使用。
2.同步互斥方法:
- Event 事件:
from multiprocessing import Event
- 創建事件對象:
e = Event() - 事件阻塞:
e = wait([timeout]) - 事件設置:
e.set()
對事件對象進行設置,此時wait判斷如果事件被set則結束阻塞
e處於設置狀態,e.wait()不在阻塞 - 事件清除:
e.clear()
e處於未設置狀態,e.wait()阻塞 - 事件判斷:
e.is_set()
判斷e的當前狀態.檢測對象是否被設置,設置返回True,事件阻塞爲False
示例1:
# event_test.py
from multiprocessing import Event
# 創建事件對象
e = Event()
print(e.is_set())
e.set()
# 將設置清除 wait又堵塞
e.clear()
e.wait()
print(e.is_set())
示例2:
from multiprocessing import Process,Event
from time import sleep
def wait_event():
print('想操作臨界區但是要等待事件設置')
e.wait()
print('終於輪到我操作臨界區了',e.is_set())
def wait_event_timeout():
print('也想操作臨界區但是也要等2秒吧')
e.wait(2)
print('2秒到了我不等了',e.is_set())
e = Event()
p1 = Process(target=wait_event)
p2 = Process(target=wait_event_timeout)
p1.start()
p2.start()
print('假裝主進程在操作臨界資源')
sleep(3)
e.set()
print('開放臨界資源')
p1.join()
p2.join()
--------------------------------------
假裝主進程在操作臨界資源
想操作臨界區但是要等待事件設置
也想操作臨界區但是也要等2秒吧
2秒到了我不等了 False
開放臨界資源
終於輪到我操作臨界區了 True
----------------------------------------------------------------------
- 鎖 Lock
from multiprocessing import Lock
- 創建鎖對象:
lock = Lock() - 上鎖:
lock.acquire() 上鎖 - 解鎖:
lock.release()
上鎖狀態:此時執行acquire()操作會阻塞
解鎖狀態:執行acquire()操作爲非阻塞 - with lock:----> 上鎖
…
…
-----> with代碼段結束後自動解鎖
示例:
from multiprocessing import Process,Lock
import sys
from time import sleep
# sys.stdout標準輸出流作爲所有進程的臨界資源
def writer1():
# 上鎖
lock.acquire()
for i in range(5):
sleep(1)
sys.stdout.write('writer1輸出\n')
# write不會自動換行,所以加上\n
# 解鎖
lock.release()
def writer2():
# with方式上鎖
with lock:
for i in range(5):
sleep(1)
sys.stdout.write('writer2輸出\n')
# with代碼段結束後自動解鎖
# 創建鎖
lock = Lock()
w1 = Process(target=writer1)
w2 = Process(target=writer2)
w1.start()
w2.start()
w1.join()
w2.join()
在終端打印結果:
# 輸出5個writer1,輸出5個writer2.誰先搶佔到誰先輸出5個