一. 守护进程
守护进程: 主进程的代码运行结束,守护进程也跟着结束
1 主进程创建守护进程 2 其一:守护进程会在主进程代码执行结束后就终止 3 其二: 守护进程内无法才开启子进程, 否则抛出异常: 4 AssertionError: daemonic processes are not allowed to have children 5 注意: 进程之间是相互独立的, 主进程代码运行结束,守护进程随机终止
代码如下:
from multiprocessing import Process import time def fun(): time.sleep(2) print('子进程打印不出来') if __name__ == '__main__': p = Process(target=fun ) p.daemon = True #守护进程 p.start() print('结束')
二. 进程同步
1. 同步锁(互斥锁) ***************
保证数据安全用的,但是将锁起来的那段代码的执行变成了同步\串行,
牺牲了效率,保证了安全
from multiprocessing import Lock
l = Lock()
l.acquire() #锁住
数据操作
l.release() #释放
#由并发变成了串行,牺牲了运行效率,但避免了竞争 from multiprocessing import Process,Lock import os,time def work(n,lock): #加锁,保证每次只有一个进程在执行锁里面的程序,这一段程序对于所有写上这个锁的进程,大家都变成了串行 lock.acquire() print('%s: %s is running' %(n,os.getpid())) time.sleep(1) print('%s:%s is done' %(n,os.getpid())) #解锁,解锁之后其他进程才能去执行自己的程序 lock.release() if __name__ == '__main__': lock=Lock() for i in range(5): p=Process(target=work,args=(i,lock)) p.start()
2. 信号量
Semaphore 内部维护了一个计数器, acquire-1,release + 1, 当计数器为0的时候
,阻塞其他的进程
1 互斥锁同时只允许一个线程更改数据,而信号量Semaphore是同时允许一定数量的线程更改数据 。 2 假设商场里有4个迷你唱吧,所以同时可以进去4个人,如果来了第五个人就要在外面等待,等到有人出来才能再进去玩。 3 实现: 4 信号量同步基于内部计数器,每调用一次acquire(),计数器减1;每调用一次release(),计数器加1.当计数器为0时,acquire()调用被阻塞。这是迪科斯彻(Dijkstra)信号量概念P()和V()的Python实现。信号量同步机制适用于访问像服务器这样的有限资源。 5 信号量与进程池的概念很像,但是要区分开,信号量涉及到加锁的概念
1 # semaphre 信号量 锁 原理跟锁差不多,但可以限制数量 2 import time 3 from multiprocessing import Semaphore,Process 4 5 def fun(n,l): 6 l.acquire() 7 print('%s开始' %n) 8 time.sleep(1) 9 print('%s结束>>>' %n) 10 time.sleep(1) 11 l.release() 12 if __name__ == '__main__': 13 l = Semaphore(4) 14 for i in range(10): 15 p = Process(target=fun,args=(i,l)) 16 p.start()
3. 事件
e = Even(), 事件初始状态为False, 当事件为False,e.wait()的地方会阻塞,e.set()
将e 的状态改为
True,如果e的状态为True,wait的地方就不等待了,不阻塞了,
e.clear() 将e的状态改为False,
查看e的状态: is_set,
1 # Event 事件 2 3 # from multiprocessing import Event 4 # 5 # e = Event() #有两个状态 默认TURE wait Fase 6 # print(1) 7 # print(e.is_set()) #查看当前状态 8 # e.set() #设置状态为TURE 9 # print(e.is_set()) 10 # e.clear() #清空状态, False 11 # print(e.is_set()) 12 # 13 # e.wait() #状态为False 就会被阻塞 14 # print('结束')
三. 进程通信(IPC)
队列 **************
队列: 进程安全的,能够保证数据安全,
Q = queue(4), 给队列设定一个固定的长度, q.put(),
q.get(),q.get_nowait(),q.get(False),
Q.put() 在队列满了的时候会阻塞和q.get在队列空了之后会阻塞
Q.put_nowait()
Q.full q.empty
# from multiprocessing import Queue # q = Queue(3) # q.put('灰机1号') # q.put('2') # q.put(3) # print(q.empty()) #判断是否为空 # print(q.qsize()) #返回多少个数量 # print(q.get()) # print(q.get()) # print(q.get()) # # print(q.get()) # q为空时将会被阻塞******* # print(q.full()) #判断q已满 # print(q.get_nowait()) # # print(q.get_nowait()) # # print(q.get_nowait()) # # # print(q.get_nowait()) # q为空时报错 queue.Empty******* # q.get(False) #同上 会报错
1 # 基于队列的进程通信 2 # from multiprocessing import Process,Queue 3 # def fun(q): 4 # a = q.get() 5 # print('>>>>:', a) 6 # if __name__ == '__main__': 7 # q = Queue(9) 8 # q.put('奥术大师多') 9 # p = Process(target=fun,args=(q,)) 10 # p.start() 11 # 12 # print('主进程结束')
# Queue # import time # from multiprocessing import Process,Queue # # def shengchan(q): # for i in range(10): # time.sleep(1) # q.put('包子%s号' %i) # print('包子%s号生产完毕' %i) # q.put(None) # def xiaofei(q): # while 1: # time.sleep(1.5) # a = q.get() # if a == None: # break # print('%s被吃' %a) # # if __name__ == '__main__': # q = Queue(10) # p1 = Process(target=shengchan,args=(q,)) # p2 = Process(target=xiaofei,args=(q,)) # p1.start() # p2.start() # print('结束')
生产者消费者模型
缓冲区解耦的事情
Joinablequeue, 能记录着你往队列里面put的数据量
其他方法和queue 是一样的,比queue多了两个方法: q.task_done,q.join
1 # JoinableQueue 2 # import time 3 # from multiprocessing import Process,JoinableQueue 4 # 5 # def shengchan(q): 6 # for i in range(10): 7 # time.sleep(1) 8 # q.put('包子%s号' %i) 9 # print('包子%s号生产完毕' %i) 10 # q.join() 11 # def xiaofei(q): 12 # while 1: 13 # time.sleep(1.5) 14 # a = q.get() 15 # print('%s被 吃' %a) 16 # q.task_done() 17 # 18 # if __name__ == '__main__': 19 # q = JoinableQueue(10) 20 # p1 = Process(target=shengchan,args=(q,)) 21 # p2 = Process(target=xiaofei,args=(q,)) 22 # p2.daemon = True 23 # p1.start() 24 # p2.start() 25 # print('结束')