一同步与异步
同步执行:一个进程在执行任务时,另一个进程必须等待执行完毕,才能继续执行
异步执行:一个进程在执行任务时,另一个进程无需等待其执行完毕就可以执行,当有消息返回时,系统会提醒后者进行处理,这样会很好的提高运行效率
二守护进程
主进程创建守护进程过程:
一 :守护进程代码在主进程结束后就终止
二:守护进程无法再开启子进程,否则抛出异常AssertionError: daemonic processes are not allowed to have children
进程之间石相互独立的,主进程运行结束,守护进程随即结束
from multiprocessing import Process import time,random class piao(Process): def __init__(self,name): self.name=name super().__init__() def run(self): print('%s is piaoing'%self.name) time.sleep(random.randint(1,3)) print('%s is piao end'%self.name) p=piao('一根') p.daemon=True #一定要在p.start()前设置,设置p为守护进程,禁止p创建子进程,并且父进程代码执行结束,p即终止运行 p.start() print('主')
from multiprocessing import Process from threading import Thread import time def foo(): print(123) time.sleep(1) print('end123') def bar(): print(456) time.sleep(2) print('end456') p1=Process(target=foo) p2=Process(target=bar) p1.daemon=True p1.start() p2.start() print("main-------") #打印该行则主进程代码结束,则守护进程p1应该被终止,可能会有p1任务执行的打印信息123,因为主进程打印main----时,p1也执行了,但是随即被终止
三进程同步(加锁)
加锁可以保证多个进程修改同一块数据时,同一时间只能有一个任务可以进行修改,即串行的修改,没错,速度是慢了,但牺牲了速度却保证了数据安全。
虽然可以用文件共享数据实现进程间通信,但问题是:
1.效率低
2.需要自己加锁处理
为此mutiprocessing模块为我们提供了基于消息的IPC通信机制:队列和管道。
1 队列和管道都是将数据存放于内存中
2 队列又是基于(管道+锁)实现的,可以让我们从复杂的锁问题中解脱出来,
我们应该尽量避免使用共享数据,尽可能使用消息传递和队列,避免处理复杂的同步和锁问题,而且在进程数目增多时,往往可以获得更好的可获展性。
part1:多个进程共享同一打印终端
并发运行,效率高,但竞争同一打印终端,带来了打印错乱
from multiprocessing import Process import os,time def work(): print('%s is running' %os.getpid()) time.sleep(2) print('%s is done' %os.getpid()) if __name__ == '__main__': for i in range(3): p=Process(target=work) p.start()
由并发变成了串行,牺牲了运行效率,但避免了竞争
from multiprocessing import Process,Lock import os,time def work(lock): lock.acquire() print('%s is running' %os.getpid()) time.sleep(2) print('%s is done' %os.getpid()) lock.release() if __name__ == '__main__': lock=Lock() for i in range(3): p=Process(target=work,args=(lock,)) p.start()
part2:多个进程共享同一文件
文件当数据库,模拟抢票
#文件db的内容为:{"count":1} #注意一定要用双引号,不然json无法识别 from multiprocessing import Process,Lock import time,json,random def search(): dic=json.load(open('db.txt')) print('