同步和互斥
临界资源
对多个进程或者线程都可见的资源,容易产生争夺,这类资源称为临界资源
临界区
对临界资源进行操作的代码区域称为临界区
解决资源争夺
同步或者互斥
同步
同步是一种合作关系,为完成某种任务,多进程或者多线程之间形成一种协调,按照约定或条件执行操作临界资源。
互斥
互斥是一种制约关系,当一个进程或者线程使用临界资源时进行上锁处理,当另一个进程使用时会阻塞等待,直到解锁后才能继续使用。
进程同步机制
事件
通过设置阻塞,方便对临界资源进行操作
事件基本函数
from multiprocessing import Event
#创建事件对象
e = Event()
# 设置事件阻塞,直到e被set之后才结束阻塞
e.wait([timeout])
# 事件设置 当事件被设置后e.wait()不再阻塞
e.set()
# 事件状态判断,判断e是否被设置的状态
e.is_set()
# 清除设置 当事件设置被clear后 e.wait又会阻塞
e.clear()
事件实现示例
# event.py
from multiprocessing import Event,Process
import os
from time import sleep
def fun1():
print('进程1想要操作临界区')
# 进入阻塞状态
e.wait()
with open('file.txt') as f:
print('进程1:',f.read())
def fun2():
print('进程2也要操作临界区')
# 2s后不在阻塞
e.wait(2)
if e.is_set():
with open('file.txt') as f:
print('进程2:',f.read())
else:
print('我靠,我没读到内容')
# 创建事件对象
e = Event()
p1 = Process(target = fun1)
p2 = Process(target = fun2)
p1.start()
p2.start()
sleep(3)
with open('file.txt','w') as f:
f.write('I love China')
# 设置后e.wait()不再阻塞
e.set()
p1.join()
p2.join()
锁
acquire()
为一个条件阻塞函数,当有任意一个进程先进行了acquire
操作后,其他进程再企图进行acquire
操作时就会阻塞,直到lock
对象被release
后其他进程才可进行下一次acquire
操作
锁基本函数
# 创建锁对象
lock = Lock()
# 上锁,如果锁已经是上锁状态调用此函数会阻塞
lock.acquire()
# 解锁
lock.release()
# 实现加锁解锁
with lock
锁实现示例
# lock.py
from multiprocessing import Lock,Process
import sys
def fun1():
# 加锁
lock.acquire()
for i in range(10):
sys.stdout.write('fun1\n')
# 解锁
lock.release()
def fun2():
# 加锁
# lock.acquire()
with lock:
for i in range(10):
sys.stdout.write('fun2\n')
# 解锁
# lock.release()
# 创建锁对象
lock = Lock()
p1 = Process(target = fun1)
p2 = Process(target = fun2)
p1.start()
p2.start()
p1.join()
p2.join()