临界资源:多个进程或者线程都能操作的共享资源
临界区:操作临界区资源的代码段
同步:同步是一种合作关系,为完成某个任务,多进程或者多线程之间形成的一种协调关系
互斥:互斥是一种制约关系,
multiprocessing 多进程之间相互协调的方式有如下几种(进程同步的几种方法):
Lock:
一个Lock对象有两个方法acquire和release来控制共享数据的读写权限。
Event:
一个进程发事件的信号,另一个进程等待事件的信号。Event对象有两个方法set和clear来管理自己内部的变量。
Semaphore:
用来共享资源(限制执行任务数)。
RLock:递归锁对象。
Barrier:将程序分成几个阶段,适用于有些进程必须在某些特性进程之后执行,处于Barrier之后的代码不能同处于Barrier之前的代码并行。
Condition:此对象用来同步部分工作流程,在并行的进程中,有两个基本的方法,wait()用来等待进程,notify_all用来通知所有等待此条件的进程。
Pipe:管道
注意:Barrier是py3才有。
Barrier:表示的是一种屏障,当若干个进程没有达到屏障数量的是会都处于阻塞的状态之下,如果一旦达到的了限定的屏障数的时候,那么会自动的解除状态且自动的启动运行。
Barrier的语义理解就是:每个任务按规定的分组数进行任务执行,如果没有达到规定的分组数,则需要一直阻塞等待满足规定的分数组(屏障点)才会可以执行任务。
创建对象:Barrier(parties, action=None, timeout=None)
方法:
wait(timeout=None) 尝试通过障碍并阻塞。
返回值是一个在0到parties-1范围内的整数,每个线程都不同。其中一个线程在释放之前将调用action。如果此调用引发错误,则障碍将进入断开状态。
reset() 重置障碍,返回默认的空状态,即当前阻塞的线程重新来过。见例二
abort() 将障碍置为断开状态,这将导致已调用wait()或之后调用wait()引发BrokenBarrierError。
示例:
#!/usr/bin/evn python
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
文件名称 : jincheng12
文件功能描述 : 功能描述
创建人 : 小钟同学
创建时间 : 2021/5/8
-------------------------------------------------
修改描述-2021/5/8:
-------------------------------------------------
"""
import time
from multiprocessing import Process
from multiprocessing import current_process,Barrier
def barrier_action():
print('组队完成!')
def tacks_action(barrier):
print("【%s】进入开始执行任务前的准备"%(current_process().name))
time.sleep(3)
barrier.wait() # 进入到一个屏障点等待
print("【%s】准备完成!---正式执行任务" % (current_process().name))
if __name__ == '__main__':
time1 = time.time()
barrier = Barrier(parties=3,action=barrier_action)# 需三个人一组,每满三人则调用barrier_action
pslist = [Process(name="队员编号:%s"%(i),target=tacks_action,args=(barrier,)) for i in range(10) ]
for ps in pslist:
ps.start()
ps.join(timeout=5)
# 结束同步蓝山的锁定
# 将障碍置为断开状态,这将导致已调用wait()或之后调用wait()引发brokenbarriererror
barrier.abort()
time2 = time.time()
print("计算用时:", time2-time1)
结果输出:
$ python jincheng13.py
【队员编号:0】进入开始执行任务前的准备
【队员编号:1】进入开始执行任务前的准备
【队员编号:2】进入开始执行任务前的准备
组队完成!
【队员编号:2】准备完成!---正式执行任务
【队员编号:0】准备完成!---正式执行任务
【队员编号:1】准备完成!---正式执行任务
【队员编号:3】进入开始执行任务前的准备
【队员编号:4】进入开始执行任务前的准备
【队员编号:5】进入开始执行任务前的准备
组队完成!
【队员编号:5】准备完成!---正式执行任务
【队员编号:4】准备完成!---正式执行任务
【队员编号:3】准备完成!---正式执行任务
【队员编号:6】进入开始执行任务前的准备
【队员编号:7】进入开始执行任务前的准备
【队员编号:8】进入开始执行任务前的准备
组队完成!
【队员编号:8】准备完成!---正式执行任务
【队员编号:6】准备完成!---正式执行任务
【队员编号:7】准备完成!---正式执行任务
【队员编号:9】进入开始执行任务前的准备
计算用时:45.044153928756714
Process 队员编号:9:
Traceback (most recent call last):
File "C:\Users\mayn\AppData\Local\Programs\Python\Python35-32\lib\multiprocessing\process.py", line 252, in _bootstrap
self.run()
File "C:\Users\mayn\AppData\Local\Programs\Python\Python35-32\lib\multiprocessing\process.py", line 93, in run
self._target(*self._args, **self._kwargs)
File "D:\ceshi\jincheng13.py", line 23, in tacks_action
barrier.wait() # 进入到一个屏障点等待
File "C:\Users\mayn\AppData\Local\Programs\Python\Python35-32\lib\threading.py", line 610, in wait
self._wait(timeout)
File "C:\Users\mayn\AppData\Local\Programs\Python\Python35-32\lib\threading.py", line 650, in _wait
raise BrokenBarrierError
threading.BrokenBarrierError
上面的错误异常是因为、:我们给出10个人,但是条件是3人一组,但是当我们的分配了新的人员之后,它处于等待状态种,
但是我们的强制进行打断barrier.abort(),将屏障至于broken状态,所以等待中的进程或者调用等待方法的进程此时都会抛出BrokenBarrierError异常,直到reset方法恢复屏障。
此时我修改为9个则无异常!
pslist = [Process(name="队员编号:%s"%(i),target=tacks_action,args=(barrier,)) for i in range(9) ]
https://www.jianshu.com/p/b4ee3c32c06d/
个人其他博客地址
简书:https://www.jianshu.com/u/d6960089b087
掘金:https://juejin.cn/user/2963939079225608
小钟同学 | 文 【原创】| QQ:308711822
1:本文相关描述主要是个人的认知和见解,如有不当之处,还望各位大佬指正。 2:关于文章内容,有部分内容参考自互联网整理,如有链接会声明标注;如没有及时标注备注的链接的,如有侵权请联系,我会立即删除处理哟。
原文作者:程序员小钟同学;如有侵权,请联系管理员删除。