python 64式: 第16式、进程池

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import multiprocessing
import time

from concurrent import futures


'''
关键:
1、进程池提出原因:同时创建很多进程是需要消耗资源的,可以创建几个进程,其他任务在等待线程池中线程
完成,就可以继续处理
本质:将任务提交到进程池的任务队列中
组成:等待队列和一系列进程

2、 concurrent.futures.Executor
作用:抽象类,有异步执行调用方法。有两个子类:
ThreadPoolExecutor(max_workers)和ProcessPoolExecutor(max_workers)
max_workers:表示有多少worker并行执行该任务,异步调用,若为None,则设置为机器的处理器数目

3、 Executor.submit(fn, *args, **kwargs)
作用:调度函数的执行
参数: fn: 异步执行的函数,*args: fn的参数,**kwargs: fn的参数
返回值: 返回一个Future对象,表示可调用的执行
注意: submit是立即返回的

4、 Executor.map(function, *iterables, timeout=None):
作用:将argument作为参数执行函数,以异步方式执行;相当于map(func, *iterables)
但是func是异步执行,如果操作超时,返回错误;不指定timeout,则不设置超时
参数: func:异步执行函数,*iterables:可迭代对象,如列表,每一次func执行,都会从iterables中取参数

5、 Executor.shutdown(wait=True)
作用:释放系统资源,在submit()或map()等异步操作之后调用,使用with语句可以避免显示调用该方法


6、 concurrent.futures.as_completed(fs, timeout=None)
作用:接收一个future列表,返回一个迭代器,在运行结束后删除future,一次取出所有任务的结果
本质:是生成器,任务还没有完成,会阻塞;先完成任务会先通知主线程
as_completed()是按照完成时间输出的
map()是按照输入参数的顺序输出的,有顺序要求请用map

7 关于concurrent.futures.Future
concurrent.future: 未来完成的操作,异步编程
cancel():取消调用,若执行,不能取消;返回值表示是否可以取消
cancelled():返回是否已经取消
done():返回任务是否已经成功完成
result(timeout=None):返回调用的结果,如果还没有完成,将会等待一定时间
exception(timeout=None):返回调用的异常
wait(fs, timeout=None, return_when=ALL_COMPLETED):让主线程阻塞,直到满足设定的要求
参数:等待的任务序列,超时时间,等待条件。ALL_COMPLETED表示要等待所有任务完成。

总结:
进程池:不受GIL全局解释器锁的限制,缩短执行时间,使用多核处理的模块,推荐使用
线程池:不管多少处理器,运行的时候只有一个线程运行。【协程:多个线程之间互相渡让cpu的控制权】
线程池/进程池 适用:处理多个客户端请求的服务端部分

参考:
[1] https://www.jianshu.com/p/b9b3d66aa0be
[2] http://lovesoo.org/analysis-of-asynchronous-concurrent-python-module-concurrent-futures.html
[3] https://python-parallel-programmning-cookbook.readthedocs.io/zh_CN/latest/chapter4/02_Using_the_concurrent.futures_Python_modules.html
[4] https://docs.python.org/3/library/concurrent.futures.html
[5] https://docs.python.org/3/library/concurrent.futures.html
[6]https://www.jianshu.com/p/4fab1ffe8665
[7]https://docs.python.org/3.2/library/concurrent.futures.html
'''

def run(num, **kwargs):
    time.sleep(num)
    return kwargs

def processPoolExecutorAsCompleted():
    with futures.ProcessPoolExecutor(max_workers=multiprocessing.cpu_count()) as executor:
        futureList = [executor.submit(run, i, **{str(i): i} ) for i in range(6, 0, -1)]
    results = []
    # as_completed()是按照完成时间输出的
    # map()是按照输入参数的顺序输出的
    for future in futures.as_completed(futureList):
        result = future.result()
        results.append(result)
    return results

def valid():
    result = processPoolExecutor_as_completed()
    print result

def runMap(num):
    time.sleep(num)
    return num

def processPoolExecutorMap():
    datas = [i for i in range(6, 0, -1)]
    with futures.ProcessPoolExecutor(max_workers=multiprocessing.cpu_count()) as executor:
        results = list(executor.map(runMap, datas))
        return results

def process():
    result = processPoolExecutorAsCompleted()
    print result
    results = processPoolExecutorMap()
    print results

if __name__ == "__main__":
    process()

猜你喜欢

转载自blog.csdn.net/qingyuanluofeng/article/details/83869205