进程池和线程池

我们知道多进程可以利用多核CPU进行并行计算,但多进程的资源开销很大,因此不可能无限开。举个栗子,假设有100块砖,是请5个人去搬,还是请100个人去搬?答案是5个人,100个人工钱太贵了。。。这就和开多进程是一样的道理。那如何限制进程数量呢?通过进程池。

Pool可以提供指定数量的进程,供用户调用,当有新的请求提交到pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到规定最大值,那么该请求就会等待,直到池中有进程结束,就重用进程池中的进程。

from multiprocessing import Pool
import os, time

def foo(i):
    print('进程【%s】,id-->%s'%(i,os.getpid()))
    time.sleep(2)

if __name__ == '__main__':
    pool = Pool(4)  # 指定进程池大小,默认为CPU核心数
    for i in range(1,10):
        pool.apply_async(func=foo, args=(i,)) # 如果没有返回计算结果就不用赋值


    pool.close()    # 关闭进程池
    pool.join() # 等待进程池内任务处理完,否则主进程走完就结束了

进程池的方法:
pool = Pool() 创建进程池
pool.apply(func=func_name, args=()) 从进程池里取一个进程并执行
pool.apply_async(func=func_name, args=()) apply的异步版本
apply() 和apply_async的返回值是结果对象obj, 通过obj.get()可以收集结果。
pool.close() 关闭进程池
pool.terminate() 终止所有工作进程
pool.join() 主进程等待所有子进程执行完毕,必须在close或terminate之后

Python3 中的进程池和线程池

python3中针对进程池和线程池提供了更易用的接口。使用方式也是一样的:

from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor # 导入
import random, time


def get_html(url):
    print('请求%s' % url)
    time.sleep(random.randint(1, 3))
    return '%s html......' % url


def parse_html(res):
    html = res.result()  # 任务完成返回的是结果对象,回调函数接收该对象通过.result()获取真实结果
    print(html)


if __name__ == "__main__":
    start = time.time()

    pool = ProcessPoolExecutor(4)  # 默认进程池大小等于CPU核心数
    # pool = ThreadPoolExecutor(6)  # 线程池一般20-30左右足够,可以根据任务适当调整

    urls = ['url_1', 'url_2', 'url_3', 'url_4', 'url_5', 'url_6']
    for url in urls:
        pool.submit(get_html, url).add_done_callback(parse_html)  # 提交任务到进程池并指定回调函数,即子进程执行结果出来后,通知主进程处理结果(执行回调函数)

    pool.shutdown(wait=True)  # 关闭进程等待任务结束;这里主要是为了阻塞主进程,统计时间用

    end = time.time()
    print('一共耗时:', end - start)

    """
    请求url_1
    请求url_2
    请求url_3
    请求url_4
    请求url_5
    url_1 html......
    请求url_6
    url_4 html......
    url_6 html......
    url_5 html......
    url_2 html......
    url_3 html......
    一共耗时: 3.2524783611297607
    """

可以看到,如果要用线程,只需要实例化线程池对象即可。使用非常方便。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值