3 - Python内置模块 - concurrent模块

本文详细介绍了Python内置的concurrent模块,包括future模块、ThreadPoolExecutor和ProcessPoolExecutor的使用,以及Future对象的方法。通过实例展示了如何进行异步爬虫任务,强调了concurrent模块在简化多线程、多进程编程中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章目录

1 conturrent包

conturrent包内只包含了一个future模块,它为异步执行调用提供了高级的接口。

2 future模块

主要提供了两个用于异步执行的类:

  • ThreadpPoolExecutor:异步调用的线程池的执行器
  • ProcessPoolExecutor:异步调用的进程池的执行器

两者实现相同的接口,该接口由抽象Executor类定义。

3 ThreadPoolExecutor对象

提供了以下方法用于构建和执行多线程任务:

方法含义
ThreadpPoolExecutor(max_workers=None, thread_name_prefix=’’)池中至多创建max_workers个线程的池来同时异步执行,返回Executor实例,如果max_workers没有指定,那么会开启cpu核数(或1) * 5 个线程
submit(fn, *args, **kwargs)提交执行的函数及其参数,返回Future类的实例
shutdown(wait=True)清理池

基本使用:

import concurrent.futures

def worker(name, count=1000):
    total = 0
    for i in range(count):
        total += 1
    return name, total

fs = []
executor = concurrent.futures.ThreadPoolExecutor(max_workers=3)  # 线程池为3
for i in range(3):
    f = executor.submit(worker, 'worker-{}'.format(i), 10000)    # 提交即异步执行
    fs.append(f)

for f in fs:
    print(f.result())    # 获取结果
    
executor.shutdown()  # 等待所有进程执行完毕后,关闭线程池。

# ('worker-0', 10000)
# ('worker-1', 10000)
# ('worker-2', 10000)

submit返回的是一个Future对象。当执行的任务多余线程池的数量时,超出的任务会被阻塞,即等待执行状态,打印对象即可查看

<Future at 0x2456e953cc0 state=running>
<Future at 0x2456ec65588 state=running>
<Future at 0x2456ec6d7b8 state=running>  # 运行
<Future at 0x2456ec6dac8 state=pending>  # 阻塞等待
<Future at 0x2456eeba0f0 state=pending>

4 Future对象

包含了许多针对多进程/线程执行的相关结果的方法。

方法含义
done()如果调用被成功取消或者执行完成,返回True
cancelled()如果调用被成功取消,返回True
running()如果正在运行且不能被取消,返回True
cancel()尝试取消调用。如果已经执行且不能取消返回False,否则成功取消返回True
result(timeout=None)获取执行结果,timeout为None,表示阻塞等待。
timeout到期还未返回,抛出concurrent.futures._base.TimeoutError异常
exception(timeout=None)获取返回的异常,timeout为None,表示阻塞等待。
timeout到期还未返回,抛出concurrent.futures._base.TimeoutError异常

5 ProcessPoolExecutor对象

实现了和ThreadPoolExecutor一样的接口,所以只需要把上面例子的ThreadPoolExecutor换为ProcessPoolExecutor即可完成进程的创建。

import concurrent.futures

def worker(name, count=1000):
    total = 0
    for i in range(count):
        total += 1
    return name, total

if __name__ == '__main__':

    fs = []
    executor = concurrent.futures.ProcessPoolExecutor(max_workers=3)
    for i in range(5):
        f = executor.submit(worker, 'worker-{}'.format(i), 10000)
        print(f)
        fs.append(f)

    for f in fs:
        print(f.result())

# ('worker-0', 10000)
# ('worker-1', 10000)
# ('worker-2', 10000)

6 支持上下文管理

当进程吃使用完毕时,我们需要调用shutdown方法来关闭它。ThreadPoolExecutor和ProcessPoolExecutor实现了上下文管理,当我们离开时,会自动调用shutdown方法,非常方便

import concurrent.futures

def worker(name, count=1000):
    total = 0
    for i in range(count):
        total += 1
    return name, total

if __name__ == '__main__':

    fs = []
    executor = concurrent.futures.ProcessPoolExecutor(max_workers=3)
    with executor:
        for i in range(5):
            f = executor.submit(worker, 'worker-{}'.format(i), 10000)
            print(f)
            fs.append(f)

        for f in fs:
            print(f.result())

该库统一了线程池,进程池的调用,简化了编程。唯一的缺点是无法设置线程的名称,但这都无所谓了。

7 异步爬网站的小例子

import concurrent.futures
import requests


def get_html(url):
    response = requests.get(url)
    length = len(response.text)
    return length, response.text


if __name__ == '__main__':
    url_list = [
        'http://www.baidu.com',
        'http://www.sina.com',
        'http://www.qq.com',
    ]
    with concurrent.futures.ProcessPoolExecutor(max_workers=3) as executor:
        fs = [executor.submit(get_html, url) for url in url_list]
        for f in fs:
            print(f.result())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值