Bootstrap

Python进程池使用

"""
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)
        
"""
;