zoukankan      html  css  js  c++  java
  • python_并发编程——进程池

    1.进程池

    from multiprocessing import Pool
    
    def func(n):
        for i in range(10):
            print(n+1)
    
    if __name__ == '__main__':
        pool = Pool(3)  #启动有三个进程的进程池。
        #第一个参数进程要访问的代码,第二个参数必须是一个可迭代参数,规定了要执行的任务数
        pool.map(func,range(100))   #100个任务

    结果:  每个数打印了10次。

    2.进程池和多进程的用时对比

    def func(n):
        for i in range(10):
            print(n + 1)
    
    if __name__ == '__main__':
        start = time.time()
        pool = Pool(3)  #启动有三个进程的进程池。
        #第一个参数进程要访问的代码,第二个参数必须是一个可迭代参数,规定了要执行的任务数
        pool.map(func,range(100))   #100个任务
        t1 = time.time() - start
    
        start = time.time()
        p_list = []
        for i in range(100):
            p = Process(target=func,args=(i,))
            p_list.append(p)
            p.start()
        for p in p_list:
            p.join()
        t2 = time.time() - start
        print(t1,t2)

    结果:  进程池的用0.9,而多进程的用了17+

    3.进程池的另一种实现方式

    from multiprocessing import Pool
    import time
    import os
    
    def func(n):
        print('start func{}'.format(n),os.getpid())
        time.sleep(1)
        print('end func{}'.format(n),os.getpid())
    
    if __name__ == '__main__':
        p = Pool(5)
        for i in range(10):
            # (调用的方法,传递参数(以元组的形式传递参数))
            p.apply_async(func,args=(i,))
        p.close()   #结束进程池接收任务
        p.join()    #感知进程池中的任务执行结束

    结果:  可以看到有任务执行完毕后,进程被新的任务利用。apply_async()方法如果想执行完,再继续执行主进程中的代码必须配合 close()方法和join()方法使用。

    4.进程池的返回值

    from multiprocessing import Pool
    import time
    
    def func(n):
        time.sleep(0.5)
        return n*n      #返回值
    
    if __name__ == '__main__':
        p = Pool()
        for i in range(10):
            res = p.apply_async(func,args=(i,))     #将返回值放到res这个对象中
            print(res.get())    #get方法等待从res中获取值,但是会形成阻塞,只有get到数据时在会执行

    结果:  每0.5秒打印一个值。失去了进程池的效果。

     解决:

    from multiprocessing import Pool
    import time
    
    def func(n):
        time.sleep(0.5)
        return n*n      #返回值
    
    if __name__ == '__main__':
        p = Pool()
        res_list = []   #创建一个存储进程返回值对象的列表
        for i in range(10):
            res = p.apply_async(func,args=(i,))     #将返回值放到res这个对象中
            res_list.append(res)    #将返回值对象存放到列表中
        for i in res_list:
            print(i.get())  

    结果:  实现并发五个一组的打印子进程的返回值。

    map方法接收进程池的返回值:

    from multiprocessing import Pool
    import time
    
    def func(n):
        time.sleep(0.5)
        return n*n      #返回值
    
    if __name__ == '__main__':
        p = Pool(5)
        ret = p.map(func,range(10))
        print(ret)

    结果:,将进程池的全部返回值存放在列表中,然后一次性打印列表。

    5.进程池的回调函数

    from multiprocessing import Pool
    import os
    
    def func1(n):
        print('函数1',os.getpid())
        return n*n
    def func2(nn):
        print('回调函数2',os.getpid())
        print(nn)
    if __name__ == '__main__':
        print('主进程:',os.getpid())
        p = Pool(5)
        p.apply_async(func1,args=(10,),callback=func2)    #子进程要执行的函数  传的值  回调函数
        p.close()
        p.join()

    结果:  回调函数会接收 上面函数1的返回值,从打印的进程号可以看出,回调函数是在主进程中执行的。

  • 相关阅读:
    2021
    关于react,vue框架的搭建及bug处理
    centOS7使用
    git初探
    项目分享技术大会总结
    angular中的异常机制与异常之外的处理
    angluarjs中指令的使用方式
    Servlet知识总结
    有时候真的需要一点点改变
    story
  • 原文地址:https://www.cnblogs.com/wangdianchao/p/12088172.html
Copyright © 2011-2022 走看看