# 为什么要有进程池?
# 因为开启过多的进程并不能提高程序的运行效率,反而会降低效率
#
# 任务的分类:计算密集型、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 方法