"""
Python进程池总结:
创建进程池对象from multiprocessing import Pool
pool = Pool(5) # 进程数
阻塞式进程 apply()
pool.apply(task, args=(i,)) # task 需要执行的任务函数,args函数的入参
添加一个任务执行一个任务,如果前一个任务不结束后一个任务就不开始(并不绝对),
在阻塞式进程中,当程序发起某个耗时操作时(例如文件读写、网络通信等),
程序会一直等待,直到操作完成后才继续执行后续的指令。
非阻塞式进程apply_async()
apply_async(task, args=(i,), callback=callback_func)
与阻塞式进程相反当进程发起某个耗时操作时,程序不会阻塞(换句话说,不会一直等待操作完成后才继续执行),
而是立即返回,继续执行后续的指令,需要注意的是,使用非阻塞进程的时候并不能保证执行顺序,
完整代码:
import datetime
import os
import random
import time
from multiprocessing import Pool
def task(task_name):
print('开始做任务了', task_name)
start_time = time.time()
time.sleep(random.random() * 2)
end_time = time.time()
print('完成任务:{},用时:{},进程ID:{}'.format(task_name, str(datetime.timedelta(seconds=end_time - start_time)),
os.getpid()))
# return '完成任务:{},用时:{},进程ID:{}'.format(task_name,str(datetime.timedelta(seconds=end_time - start_time)), os.getpid())
container = []
# 用于接收非阻塞式进程 callback返回的值
def callback_func(n):
container.append(n)
if __name__ == '__main__':
# 创建一个进程池,最大进程为5个进程(子进程)
pool = Pool(5)
# 创建一个任务列表
tas = ['听音乐', '吃饭', '洗衣服', '打游戏', '散步', '做饭', '看孩子', '溜达', '出去玩']
# 循环出任务
for i in tas:
# 对应列表的每个任务通过apply提交到进程池中处理(阻塞式)
pool.apply(task, args=(i,))
# 对应列表的每个任务通过apply提交到进程池中处理(非阻塞式)
# pool.apply_async(task, args=(i,), callback=callback_func)
# 不再接受新的任务,等待已经提交的任务执行完
pool.close()
# 这个方法会让主进程阻塞,直到所有的子进程都执行完毕 需要在close之后执行
# 否则会将一直阻塞等待新任务提交,而进程池则无法处理已提交的任务
pool.join()
# print(container)
print('-' * 20)
"""