同步互斥机制:
首先需要了解几个概念:
临界资源:
临界区:
之前说了多进程之间需要遵守某些约定来对临界资源进行访问和操作,就是同步和互斥。
同步:
互斥:
主要方法:
e = Event()
e.wait([timeout])
e.set()
e.clear()
e.is_set()
代码实现:
from multiprocessing import Process,Event
from time import sleep
def test1():
print("test1想操作文件")
print("test11:", e.is_set()) # 判断事件状态
e.wait() # 设置事件阻塞
print("test12:", e.is_set()) # 判断事件状态
print("test2开始操作文件...")
with open("test.txt") as f:
print(f.read())
e.clear()
def test2():
print("test2也想操作文件")
e.wait(2) # 设置事件阻塞2秒
if e.is_set(): # 判断事件状态
with open("test.txt") as f:
print(f.read())
else:
print("test2阻塞超时,不能读取文件")
# 创建事件对象
e = Event()
p1 = Process(target = test1)
p2 = Process(target = test2)
p1.start()
p2.start()
print("主进程创建文件")
with open('test.txt','w') as f:
sleep(3)
f.write("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
e.set() # e.wait()不再阻塞
print('释放临界区使其不再阻塞')
p1.join()
p2.join()
该实例中,一个主进程和两个子进程对文件进行操作,在主进程创建文件并写入内容之前,子进程一直等待,其中一个p2子进程设置了阻塞超时时间,所以p2子进程会先执行完退出,而子进程p1会一直阻塞等待主进程调用set方法。
运行结果:
gk@gk-vm:~/python/test$ python3 process_event.py
主进程创建文件
test1想操作文件
test11: False
test2也想操作文件
test2阻塞超时,不能读取文件
释放临界区使其不再阻塞
test12: True
test2开始操作文件...
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
主要方法:
lock = Lock()
lock.acquire()
lock.release()
还有一种上锁方法
代码实现:
from multiprocessing import Process, Lock
import sys
from time import sleep
def test(n):
lock.acquire() # 上锁
for i in range(3):
print("test{}".format(n))
lock.release() # 解锁
# with lock上锁
# def test(n):
# with lock:
# for i in range(3):
# print("test{}".format(n))
# 创建锁对象
lock = Lock()
jobs = []
# 创建3个上锁的进程
for n in range(3):
p = Process(target = test, args = (n,))
p.start()
jobs.append(p)
for j in jobs:
j.join()
该实例创建了三个上锁的子进程。
运行结果:
gk@gk-vm:~/python/test$ python3 process_lock.py
test0
test0
test0
test2
test2
test2
test1
test1
test1
观察结果发现三个子进程执行顺序是无序的,但是子进程之间并没有交叉执行,说明了上锁后同一时间只能执行一个进程,其他进程都会阻塞等待,而谁先上锁是没有顺序的,进程需要自己抢占资源,决定谁先执行。
另外: