31 锁,信号量,事件,队列
1.同步锁(互斥锁)
from mutilprocessing import Lock
方式一:
lock=Lock()
lock.acquire()
数据操作的代码
lock.release()
方式二:
with lock:
数据操作代码
2.信号量
from mutilprocessing import Semaphore
一把锁,多把钥匙
s=semaphore(n) #同一时间只有n个进程进入锁里的代码
s.acquire()
数据操作代码
s.release()
3.事件
from mutilprocessing import Event
e=Event() #默认
e.set()
e.clear()
e.wait()
e.is_set()
4.
队列 Queue 进程间通信 保证数据安全(同一个数据只有一个进程能拿到)
先进先出
q=Queue()
q.put()
q.get()
q.full()
q.empty()
q.get_nowait()
q.put_nowait()
Jionablequeue 和队列类似 多了两个方法 join() task_done()
守护进程 daemon
随着父进程结束,守护进程跟着结束
p.daemon=True #必须在p.start 前加
如何将一个子进程设置为守护进程,不能在该子进程中再开子进程
生产者和消费者模型:通过一个第三方(类似缓冲区)进行解耦
from multiprocessing import Process,Lock import time def show_ticket(i): with open("file","r",encoding="utf-8") as f: num=f.read().strip() print("%s客户查看到了剩余票数:"%i,num) def func1(i,lock): show_ticket(i) print("准备开始抢票了") time.sleep(1) lock.acquire() with open("file","r",encoding="utf-") as f: num=f.read().strip() if num=="0": print("没票了") else: with open("file","w",encoding="utf-8") as f: num=int(num) num-=1 f.write(str(num)) print("%s客户抢到票了"%i) lock.release() if __name__ == '__main__': lock=Lock() for i in range(10): p=Process(target=func1,args=(i,lock)) p.start()
from multiprocessing import Event,Process e=Event()#两个状态 true false 默认为false print("开始了") print(e.is_set()) #查看事件当前的状态 #False e.set() #将当前事件状态改为true print(e.is_set())#true e.clear() #将当前事件改为flase e.wait() #事件等待 print(e.is_set())
from multiprocessing import Process,Event import time def func1(e): time.sleep(2) print("子进程一大堆运算") e.set() #将事件改为true if __name__ == '__main__': e=Event() p=Process(target=func1,args=(e,)) p.start() print("主进程开始程序") time.sleep(1) print("等待子进程通知") e.wait() print("拿到子进程通知,继续执行")
from multiprocessing import Process,Semaphore import time def func1(i,s): s.acquire() time.sleep(1) print("%s男嘉宾大保健开始"%i) time.sleep(0.5) print("%s大保健结束"%i) s.release() if __name__ == '__main__': s=Semaphore(3) #信号量和lock类似,多了参数 for i in range(10): p=Process(target=func1,args=(i,s)) p.start()
from multiprocessing import Process,Queue def func(q): ret=q.get() print(ret) if __name__ == '__main__': q=Queue(5) #队列是进程安全的 q.put("hello gril") p=Process(target=func,args=(q,)) p.start() print("主进程结束") def func(q): ret=q.get() print(ret) if __name__ == '__main__': q=Queue(3) q.put("约吗") p=Process(target=func,args=(q,)) p.start() print("主进程结束")
from multiprocessing import Process import os import time class Myprocess(Process): def __init__(self,person): super().__init__() self.person=person def run(self): print(os.getpid(),self.name) print("%s正在和女主播聊天"%self.person) if __name__ == '__main__': p=Myprocess("刘德华") p.daemon=True #一定要在p.start()之前设置p守护进程,禁止p创建子进程,并且父进程代码执行完毕,p将终止运行 p.start() time.sleep(1) print("主进程结束")
from multiprocessing import Process,Queue import time def producer(q): for i in range(10): time.sleep(1) q.put("包子%s号"%i) print("包子%s号生产完毕"%i) q.put(None) def consumer(q): while 1: baozi=q.get() if baozi==None: break time.sleep(1.5) print("%s被吃完"%baozi) if __name__ == '__main__': q=Queue(10) p1=Process(target=producer,args=(q,)) p2=Process(target=consumer,args=(q,)) p1.start() p2.start()
from multiprocessing import Process,JoinableQueue import time,random,os def producer(food,q): for i in range(10): time.sleep(random.random()) ret="%s%s"%(food,i) q.put(ret) print("%s生产了%s"%(os.getpid(),ret)) print("%s生产结束"%food) q.join() #生产完毕,使用此方法进行阻塞 ,直到队列中所有项目均被处理 # print("%s生产结束" % food) def consumer(q): while 1: ret=q.get() time.sleep(random.random()) print("%s吃了%s"%(os.getpid(),ret)) q.task_done()#向q.join()发送一次信号,证明一个数据被取走 if __name__ == '__main__': q=JoinableQueue() #生产者们 p1=Process(target=producer,args=("包子",q,)) p2=Process(target=producer,args=("玉米",q,)) p3=Process(target=producer,args=("鱼",q,)) #消费者们 c1=Process(target=consumer,args=(q,)) c2=Process(target=consumer,args=(q,)) c1.daemon=True c2.daemon=True #开始 p_1=[p1,p2,p3,c1,c2] for p in p_1: p.start() p1.join() p2.join() p3.join()
有疑问可以加wx:18179641802,进行探讨