python_并发编程——进程池

Posted 手可摘星辰。

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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的返回值,从打印的进程号可以看出,回调函数是在主进程中执行的。

以上是关于python_并发编程——进程池的主要内容,如果未能解决你的问题,请参考以下文章

Python并发编程之线程池/进程池--concurrent.futures模块

Python并发编程-进程池

2020Python修炼记python并发编程补充—进程池和线程池

python并发编程之进程池,线程池concurrent.futures

python并发编程之进程池,线程池

Python并发编程—进程池