• 【2020Python修炼记】python并发编程(六)补充—进程池和线程池


    1、

    2、 为啥要有 进程池和线程池

    进程池来控制进程数目,比如httpd的进程模式,规定最小进程数和最大进程数

    3、创建进程池的类Pool 

    如果指定numprocess为3,则进程池会从无到有创建三个进程,然后自始至终使用这三个进程去执行所有任务,不会开启其他进程

    Pool([numprocess [,initializer [, initargs]]]):创建进程池 

      参数介绍:

    numprocess:要创建的进程数,如果省略,将默认使用cpu_count()的值

    initializer:是每个工作进程启动时要执行的可调用对象,默认为None

    initargs:是要传给initializer的参数组

          方法介绍:

          主要方法:

    p.apply(func [, args [, kwargs]])
    在一个池工作进程中执行func(*args,**kwargs),然后返回结果。
    需要强调的是:此操作并不会在所有池工作进程中并执行func函数。如果要通过不同参数并发地执行func函数,必须从不同线程调用p.apply()函数或者使用p.apply_async()


    p.apply_async(func [, args [, kwargs]])
    在一个池工作进程中执行func(*args,**kwargs),然后返回结果。此方法的结果是AsyncResult类的实例,callback是可调用对象,接收输入参数。
    当func的结果变为可用时,将理解传递给callback。callback禁止执行任何阻塞操作,否则将接收其他异步操作中的结果。

    p.close()

    关闭进程池,防止进一步操作。如果所有操作持续挂起,它们将在工作进程终止前完成

    p.jion()

    等待所有工作进程退出。此方法只能在close()或 teminate()之后调用

    4、进程池和线程池

    from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
    import time
    import os
    
    
    # pool = ThreadPoolExecutor(5)  # 池子里面固定只有五个线程
    # 括号内可以传数字 不传的话默认会开设当前计算机cpu个数五倍的线程
    pool = ProcessPoolExecutor(5)
    # 括号内可以传数字 不传的话默认会开设当前计算机cpu个数进程
    """
    池子造出来之后 里面会固定存在五个线程
    这个五个线程不会出现重复创建和销毁的过程
    池子造出来之后 里面会固定的几个进程
    这个几个进程不会出现重复创建和销毁的过程
    
    池子的使用非常的简单
    你只需要将需要做的任务往池子中提交即可 自动会有人来服务你
    """
    
    
    def task(n):
        print(n,os.getpid())
        time.sleep(2)
        return n**n
    
    def call_back(n):
        print('call_back>>>:',n.result())
    """
    任务的提交方式
        同步:提交任务之后原地等待任务的返回结果 期间不做任何事
        异步:提交任务之后不等待任务的返回结果 执行继续往下执行
            返回结果如何获取???
            异步提交任务的返回结果 应该通过回调机制来获取
            回调机制
                就相当于给每个异步任务绑定了一个定时炸弹
                一旦该任务有结果立刻触发爆炸
    """
    if __name__ == '__main__':
        # pool.submit(task, 1)  # 朝池子中提交任务  异步提交
        # print('')
        t_list = []
        for i in range(20):  # 朝池子中提交20个任务
            # res = pool.submit(task, i)  # <Future at 0x100f97b38 state=running>
            res = pool.submit(task, i).add_done_callback(call_back)
            # print(res.result())  # result方法   同步提交
            # t_list.append(res)
        # 等待线程池中所有的任务执行完毕之后再继续往下执行
        # pool.shutdown()  # 关闭线程池  等待线程池中所有的任务运行完毕
        # for t in t_list:
        #     print('>>>:',t.result())  # 肯定是有序的
    """
    程序有并发变成了串行
    任务的为什么打印的是None
    res.result() 拿到的就是异步提交的任务的返回结果
    """
    View Code

    参考资料:

    https://www.cnblogs.com/linhaifeng/articles/7428874.html#_label9

  • 相关阅读:
    决定搬家
    Deklarit3.0的确不错,推荐一下。
    [Linux] 安装samba
    如何远程连接非默认端口SQL Server
    [c#] for和foreach
    svn linux客户端安装
    [c#] HttpContext.Cache和AppFabric的性能对比
    [ms sql server]计算今天是第几周
    ajax readyState的五种状态详解
    清空sql server日志
  • 原文地址:https://www.cnblogs.com/bigorangecc/p/12790061.html
Copyright © 2020-2023  润新知