python学习之进程池
3.进程池
3.1 主要的方法
p.apply_async(func[,args[,kwds]]) #非阻塞方式调用func,并行执行
func 函数名
args为传递给func的参数列表----元组形式
kwds 为传递给func的关键字参数列表
p.close() #关闭进程池,防止进一步操作(进程池不在接收新的任务)
p.join() #阻塞进程
enumerate() #不管任务是否完成,立即终止
如果使用异步提交任务,等进程池内任务都处理完,需要用get()来收集结果
使用场景:
利用python进行系统管理的时候,同时操作多个文件目录,或者远程操作多台主机,并行操作可以
节约大量的时间
阻塞:遇到I/O就发生阻塞,程序一旦遇到阻塞操作就停在原地,并且立刻释放CPU资源
非阻塞:没有遇到I/O操作,或者通过某种手段让程序即便遇到IO操作,也不会停在原地而去执行其他操作,力求尽可能多的占有cpu资源
同步和异步指的是提交任务的两种方式
同步调用:提交完这个任务后就在原地等待,知道任务运行完毕后,拿到任务的返回值,才继续执行下一行代码
异步调用:提交完任务后,不在原地等待,直接执行下一行代码
同步:我等你(当你告诉(拿到任务的返回值)我已经执行完,那我再继续往下执行)
异步:只管提交任务执行 系统会通知任务是否执行完毕
异步:不用等待当前的进程执行完毕随时根据系统调度来进行进程的切换
import os
import time
from multiprocessing import Pooldef learn(n):print("我们在做学术交流")time.sleep(2)return n**2if __name__ == '__main__':#创建进程池p = Pool(3)list1 = []for i in range(6):# apply_async异步result = p.apply_async(learn,args=(i,))#把结果添加到列表中去list1.append(result)#关闭进程池,关闭后p不再接受新的请求p.close()#等待p中所有子进程执行完成,必须放在close之后p.join()for j in list1:# 使用get来获取apply.async的结果print(j.get())同步:apply 同步阻塞,需要等待当前的子进程执行完毕后,再执行下一个进程(按顺序执行)
import os
import time
from multiprocessing import Pooldef learn(n):print("我们在做学术交流")time.sleep(2)return n ** 2if __name__ == '__main__':list1 = []p = Pool(3)for i in range(6):p.apply(learn,args=(i,))list1.append(i)print(list1)Pool创建进程池 需要使用multiprocessing.Manager()中的Queue()
进程间的通信: multiprocessing.Queue()
Manager()模块专门做数据共享,支持的类型很多:如value,array,list,dict,Queue,Lock等
multiprocessing模块下的Queue()为进程提供服务
queue模块下的Queue()为线程提供服务
队列实例化 q = Manager().Queue()
from multiprocessing import Pool,Manager
import os
def rd(q):print(f"rd启动了,{os.getpid()},父进程:{os.getppid()}")for i in range(q.qsize()): #q.size()返回队列中数据的数量print("取出数据:",q.get())def wd(q):print(f"wd启动了{os.getpid()},父进程:{os.getppid()}")for i in '123':print("wd中的:",i)q.put(i) #把字符123中的某个数据放进队列中if __name__ == '__main__':print(f"开始了{os.getpid()}")q = Manager().Queue()p = Pool()p.apply_async(wd,args=(q,))p.apply_async(rd,args=(q,))p.close() # 关闭进程池p.join() # 阻塞主进程print("结束了",os.getpid())