【同步互斥】
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个