守护进程,进程锁和进程队列
进程的一些其他方法: 进程id ( 对象.pid 或者 os.getpid() 查看父类(os.getppid()) ), 进程名字 ( 对象.name ), 查看进程是否还活着 ( 对象.is_alive() )
import os import time from multiprocessing import Process def func1(): print(111) print("1子进程的id",os.getpid()) print("1子进程的父进程id", os.getppid()) def func2(): print(222) print("2子进程的父进程id",os.getppid()) if __name__ == '__main__': p1 = Process(target=func1,) p2 = Process(target=func2, ) p1.start() p2.start() print("1子进程的id",p1.pid) print("主进程的id",os.getpid()) print(p2.is_alive()) p1.join() print(p1.is_alive())
守护进程: 父进程结束,守护进程直接结束
创建进程之前( p.start() ) 需要加上 对象.daemon = True ( p.daemon = True )
import time from multiprocessing import Process def func1(): time.sleep(1) print(111) def func2(): time.sleep(2) print(222) if __name__ == '__main__': p1 = Process(target=func1,) p2 = Process(target=func2, ) p1.daemon = True p1.start() p2.start() p2.join() #这一步如果没有,p1创建的进程就不会执行 print("卢本伟牛逼")
进程锁(同步锁/互斥锁) : 锁住进程的内容,保护数据的安全性,效率会降低. 例如抢票系统,需要用到进程锁.
上一个进程结束之后,下一个进程才会继续执行,串行进程.
Loc = Lock()
第一种方式:
Loc.acquire()
需要锁的代码
Loc.release()
第二种方式:
With loc:
需要锁的代码
import time from multiprocessing import Lock,Process def func1(n,m): with n : # n.acquire() time.sleep(0.5) print(m) #进程锁加上后,打印会等上一个进程结束之后才会打印 # n.release() if __name__ == '__main__': loc = Lock() for i in range(10): p = Process(target=func1,args=(loc,i,)) p.start()
进程队列 Queue()
q = Queue(5) #创建一个容量为5的队列
q.put() #满了会等待
q.get() #没有数据了会等待
q.qsize() #查看当前队列的内容数量
q.get_nowait() #不等待,但是报错
q.put_nowait() #不等待,但是报错
q.empty() 不可靠
q.full()不可靠
from multiprocessing import Queue q = Queue(2) q.put("义薄云天卢本伟") # 打印队列中有多少内容 print(q.qsize()) try: # 尝试再添加一个内容到队列中,如果队列有空间,就添加内容.没有就走except q.put_nowait("冰清欲洁赵梦玥") except: print("满了") # 打印队列中有多少内容 print(q.qsize()) # 打印第一次拿出的内容 print(q.get()) try: # 尝试再拿一下队列中的内容,如果有就打印,没有就走except print(q.get_nowait()) except: print("没了")
生产者消费者模型: 主要看一下JoinableQueue和Queue的队列的区别,有注释!!!
Queue:
import time from multiprocessing import Queue,Process def Shengchan(n): for i in range(10): time.sleep(0.7) a = "%s号烧饼"%(i+1) print(a+"出炉了,准备放入队列中") n.put(a) n.put(None) #因为无法判断生产多少个,为了让消费者知道生产结束,需要给队列一个不生产的信号 def Xiaofei(n): while 1 : time.sleep(1) a = n.get() if a == None: #消费者收到队列中生产者最后发送的不生产的信号,就要跳出循环 print("队列中没有烧饼了") break print(a+"被吃了") if __name__ == '__main__': q = Queue(10) s = Process(target=Shengchan,args=(q,)) x = Process(target=Xiaofei, args=(q,)) s.start() x.start()
JoinableQueue:
import time from multiprocessing import JoinableQueue,Process def Shengchan(n): for i in range(10): time.sleep(0.7) a = "%s号烧饼"%(i+1) print(a+"出炉了,准备放入队列中") n.put(a) # 给队列发送一个放入的这个任务已经处理完毕的信号(count += 1) print("=====生产完成了=====") #当生产的循环出来之后(生产完成)且消费者消费完队列里面的内容的时候,继续向下执行 #也可以说是队列结束之后,才会继续执行.( 队列的对象.join() ) n.join() #当循环结束后,生产结束且消费者也消费完,就是队列中的(count=0),才继续执行 print("=====生产者结束自己的进程=====") #执行完之后,生产者的进程就会关闭 def Xiaofei(n): while 1 : time.sleep(1) a = n.get() print(a+"被吃了") # 给队列发送一个取出的这个任务已经处理完毕的信号(count -= 1) n.task_done() if __name__ == '__main__': q = JoinableQueue(10) s = Process(target=Shengchan,args=(q,)) x = Process(target=Xiaofei, args=(q,)) s.start() #把消费者的进程设置成守护进程,总程序结束,消费者程序就结束 x.daemon = True x.start() #当生产者的进程结束之后,才继续向下执行 s.join() print("=====总进程关闭=====")