進程-同步互斥機制

【同步互斥】

1.同步互斥機制

  1. 目的:
    解決對共有資源操作產生的爭奪

  2. 臨界資源:
    多個進程或線程都能夠操作的資源(例如終端)

  3. 臨界區:
    操作臨界資源的代碼段

  4. 同步:
    同步是一種合作關係,爲完成某個任務多進程和多線程之間形成一種協調,
    按照約定或條件依次執行操作臨界資源,相互告知資源使用情況。
    (這種協調可能是因爲阻塞關係達成的)

  5. 互斥:
    互斥是一種制約關係,當一個進程或者線程進入臨界區會進行加鎖的操作。
    此時其他進程(線程)再企圖使用臨界資源時就會阻塞,直到資源被釋放才能使用。

2.同步互斥方法:

  • Event 事件:
    from multiprocessing import Event
  1. 創建事件對象:
    e = Event()
  2. 事件阻塞:
    e = wait([timeout])
  3. 事件設置:
    e.set()
    對事件對象進行設置,此時wait判斷如果事件被set則結束阻塞
    e處於設置狀態,e.wait()不在阻塞
  4. 事件清除:
    e.clear()
    e處於未設置狀態,e.wait()阻塞
  5. 事件判斷:
    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
  1. 創建鎖對象:
    lock = Lock()
  2. 上鎖:
    lock.acquire() 上鎖
  3. 解鎖:
    lock.release()
    上鎖狀態:此時執行acquire()操作會阻塞
    解鎖狀態:執行acquire()操作爲非阻塞
  4. 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個
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章