zoukankan      html  css  js  c++  java
  • 进程池-非阻塞式

    1.概述

    当需要创建的子进程数量不多时,可以直接利用multiprocessing中的Process动态生成多个进程

    但如果是上百甚至上千个目标,手动的去创建进程的工作量巨大,此时就可以用到mutiprocessing模块提供的Pool方法

    初始化Pool时,可以指定一个最大进程数,当有新的请求提交到Pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求,但如果池中的进程数已经达到指定的最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程来执行

     2.使用进程池(非阻塞式)  

    #! /usr/bin/env python
    # -*- coding:utf-8 -*-
    import os
    from multiprocessing import Process, Pool
    from random import random
    import time
    
    
    def task(task_name):
        print('开始做任务', task_name)
        start = time.time()
        # 使用sleep
        time.sleep(random()*2)
        end = time.time()
        print('完成任务:{}!用时:{},进程id:{}'.format(task_name, (end-start), os.getpid()))
    
    
    if __name__ == '__main__':
        pool = Pool(5)
        tasks = ['听音乐', '吃饭', '洗衣服', '打游戏', '散步', '看孩子', '做饭']
        for task1 in tasks:
            pool.apply_async(task, args=(task1,))  # 维持执行的进程总数为processes,当一个进程执行完毕后会添加新的进程进去
        pool.close()
        pool.join()   # 调用join之前,先调用close函数,否则会出错。执行完close后不会有新的进程加入到pool,join函数等待所有子进程结束
        print('over!')
    

     

    函数解释

    • apply_async(func[, args[, kwds[, callback]]]) 它是非阻塞,apply(func[, args[, kwds]])是阻塞
    • close()    关闭pool,使其不在接受新的任务。
    • terminate()    结束工作进程,不在处理未完成的任务。
    • join()    主进程阻塞,等待子进程的退出, join方法要在close或terminate之后使用。

    执行说明:

    创建一个进程池,并制定进程的数量为5,遍历,有7个任务提交到pool中,但是因为pool指定进程数为3,所以前5个被直接送到进程中执行,当其中一个执行完成后,才空出一个进程处理新的任务:看孩子。因为为非阻塞,主函数会自己执行自个的,不搭理进程的执行。

     3.加入回调方法

    什么是回调方法?

    1.任务完成之后调用的方法

    2.回调方法要有参数

    import os
    from multiprocessing import Process, Pool
    from random import random
    import time
    
    
    def task(task_name):
        print('开始做任务', task_name)
        start = time.time()
        # 使用sleep
        time.sleep(random()*2)
        end = time.time()
        return '完成任务:{}!用时:{},进程id:{}'.format(task_name, (end-start), os.getpid())
    
    
    container = []
    def callback_func(n):
        container.append(n)
    
    
    if __name__ == '__main__':
        pool = Pool(5)
        tasks = ['听音乐', '吃饭', '洗衣服', '打游戏', '散步', '看孩子', '做饭']
        for task1 in tasks:
            pool.apply_async(task, args=(task1,), callback=callback_func)  # 维持执行的进程总数为processes,当一个进程执行完毕后会添加新的进程进去
        pool.close()
        pool.join()   # 调用join之前,先调用close函数,否则会出错。执行完close后不会有新的进程加入到pool,join函数等待所有子进程结束
    
        for c in container:
            print(c)
        print('over!')
    

      

     进程池的好处:

    1.可以设置进程的数量

    2.可以进程复用(一个进程执行完任务后,可以接着执行下个任务)

      非阻塞的特点:全部添加到队列中,立刻返回,并没有等待其他的进程执行完毕(如把听音乐添加进去之后,并不是等听音乐这个任务执行完成之后,再添加下一个任务,而是,添加完之后,再去添加下一个任务,直到进程池满了),但是回调函数是等待任务完成之后才去调用的。

  • 相关阅读:
    百度之星资格赛1001——找规律——大搬家
    HDU1025——LIS——Constructing Roads In JGShining's Kingdom
    DP(递归打印路径) UVA 662 Fast Food
    递推DP UVA 607 Scheduling Lectures
    递推DP UVA 590 Always on the run
    递推DP UVA 473 Raucous Rockers
    博弈 HDOJ 4371 Alice and Bob
    DFS(深度) hihoCoder挑战赛14 B 赛车
    Codeforces Round #318 [RussianCodeCup Thanks-Round] (Div. 2)
    DP(DAG) UVA 437 The Tower of Babylon
  • 原文地址:https://www.cnblogs.com/GumpYan/p/12838615.html
Copyright © 2011-2022 走看看