# 为什么要有进程池? # 因为开启过多的进程并不能提高程序的运行效率,反而会降低效率 # # 任务的分类:计算密集型、IO密集型 # 计算密集型:充分占用CPU, 多进程可以充分利用多核 # IO密集型: 大部分时间都在阻塞,而不是在运行状态中,根本不适合开启多进程 # 500个任务 # 5 个进程 # 信号量机制(semaphore): 多进程共享有限的资源 # 500件衣服 任务 # 500个人 进程 # 只有4台机器 CPU # 多进程机制:多个进程并行或并发执行行,竞争资源,大量进程的创建 和销毁 ,将占用大量系统开销 # 500件衣服 任务 # 500个人 进程 # 抢4台机器 # 进程池机制(Process Pool):循环使用进程池中的进程来执行任务,可以对空闲进程进行利用,节省创建和销毁进程的开销。 # 500 件衣服 任务 # 500 个人 进程 # 4 台机器 import time from multiprocessing import Pool,Process # def func(num): # 定义一个函数,用来执行做衣服的任务 # print("做了第%s件脱衣服" % num) # # # if __name__ == '__main__': # time_start = time.time() # 如果要进行时间的计算,优先获得时间戮格式 # pool = Pool(4) # 实例化一个进程池对象 # for i in range(100): # pool.apply_async(func,args=(i,)) # 异步提交一个func到子进程中执行 # pool.close() # 关闭进程池,用户不能再向这个池中提交任务了 # pool.join() # 阻塞,直到提交到进程池中的所有任务执行结束 # time_stop = time.time() # interval = time_stop - time_start # print(interval) # 0.3530256748199463 通过进程池,来跑100个进程,耗时明显短很多,相对于多进程方式 # # # if __name__ == "__main__": # time_start = time.time() # p_list = list() # for i in range(100): # p = Process(target=func,args=(i,)) # p.start() # p_list.append(p) # for p in p_list:p.join() # 主进程 和 子进程虽然是并发执行的,但我在主进程中调用此方法,判断全部子进程 # # 运行结束,主进程再往下继续执行 # print(time.time() - time_start) # 5.312794208526611 耗时较多 # 提交任务的方法: 有同步提交 与 异步提交 # 同步提交:指的是提交的子进程之间是顺序执行的 # 异步提交:指的是提交的子进程是并发执行的 import os # def task(num): # time.sleep(1) # print("%s : %s" % (num,os.getpid())) # return num**2 # # if __name__ == '__main__': # p = Pool() # for i in range(20): # res = p.apply(task,args=(i,)) # 提交任务的方法,同步提交 即子进程是顺序执行的,相当于加了p.join() # print("--->",res) # def task(num): # time.sleep(1) # print("%s : %s" % (num,os.getpid())) # return num**2 # # if __name__ == '__main__': # print(os.cpu_count()) # p = Pool() # 如是不传参的话,进程池,进程数了为CPU的核心的数量 # for i in range(20): # p.apply_async(task,args=(i,)) # 提交任务的方法,异步提交 # p.close() # p.join() # def task(num): # time.sleep(1) # print("%s : %s" % (num,os.getpid())) # return num**2 # # if __name__ == '__main__': # p = Pool() # res_list = list() # for i in range(20): # res = p.apply_async(task,args=(i,)) # # print(res) # <multiprocessing.pool.ApplyResult object at 0x0000019FD66D43C8> # res_list.append(res) # for res in res_list:print(res.get()) # 在有返回值的情况下,res.get() ,不能在提交任务之后,立刻 # 执行,应该是先提交所有的任务,再通过 res.get()获取结果 # # def task(num): # time.sleep(1) # print("%s : %s" % (num,os.getpid())) # return num**2 # # if __name__ == '__main__': # p = Pool() # res_list = list() # for i in range(20): # res = p.apply_async(task,args=(i,)) # print(res.get()) # rss.get()没有取到结果,会阻塞,就变成了顺序执行了 def task(args): time.sleep(2) num,n = args num,n = args print(f"{num},{n} : {os.getpid()}") return num**2 if __name__ == '__main__': p = Pool() p.map(task,((1,3),)) # 实例化 传参数 进程的个数 cpus # # 提交任务: # 同步提交 apply # 返回值: 子进程 对应函数的返回值 # 一个一个顺序执行的,并没有任何并发效果 # 异步提交 apply_async # 没有返回值,要想所有任务能够顺利的执行完毕 # p.close() # p.join() 必须先close再join,阻塞直到提交到进程池中的所有任务都执行完毕。 # 有返回值的情况下 # res.get() # get不能在提交任务之后,立刻执行,应该是先提交所有的任务,然后再通过get()获取结果 # map()方法 # 异步提交的简化版本 # 自带close 和 join 方法
浙公网安备 33010602011771号