python:并发编程(十三)

这篇具有很好参考价值的文章主要介绍了python:并发编程(十三)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

本文将和大家一起探讨python提供高级接口(进程池、线程池)的并发编程,使用内置基本库concurrent.futures来实现并发,先通过官方来简单使用这个模块。先打好基础,能够有个基本的用法与认知,后续文章,我们再进行详细使用。为什么说是concurrent.futures,而不是concurrent呢?因为concurrent只有futures模块。

本文为python并发编程的第十三篇,上一篇文章地址如下:

python:并发编程(十二)_Lion King的博客-CSDN博客

下一篇文章地址如下:

python:并发编程(十四)_Lion King的博客-CSDN博客

一、快速开始

1、ProcessPoolExecutor

import concurrent.futures
import math

# 定义一些待判断的素数
PRIMES = [
    112272535095293,
    112582705942171,
    112272535095293,
    115280095190773,
    115797848077099,
    1099726899285419]

# 判断一个数是否为素数
def is_prime(n):
    if n < 2:
        return False
    if n == 2:
        return True
    if n % 2 == 0:
        return False

    sqrt_n = int(math.floor(math.sqrt(n)))
    for i in range(3, sqrt_n + 1, 2):
        if n % i == 0:
            return False
    return True

def main():
    # 使用ProcessPoolExecutor作为执行器
    with concurrent.futures.ProcessPoolExecutor() as executor:
        # 使用executor.map()方法将is_prime函数应用到PRIMES列表中的每个元素上
        # 返回的结果是一个迭代器,每个迭代项是一个二元组(number, prime),表示待判断的数和是否为素数的结果
        for number, prime in zip(PRIMES, executor.map(is_prime, PRIMES)):
            print('%d is prime: %s' % (number, prime))

if __name__ == '__main__':
    main()

该程序使用concurrent.futures模块的ProcessPoolExecutor作为执行器,将is_prime函数应用到PRIMES列表中的每个元素上,判断每个数是否为素数。

main()函数中,通过executor.map()方法将is_prime函数应用到PRIMES列表中的每个元素上,返回的结果是一个迭代器。迭代器的每个迭代项是一个二元组(number, prime),表示待判断的数和是否为素数的结果。

通过zip(PRIMES, executor.map(is_prime, PRIMES))将待判断的数和结果进行配对,然后使用for循环遍历迭代器,打印每个数是否为素数的结果。

该程序使用多进程并行执行判断素数的任务,提高了程序的执行效率。

2、ThreadPoolExecutor

import concurrent.futures
import urllib.request

# 定义要下载的网页URL列表
URLS = ['http://www.foxnews.com/',
        'http://www.cnn.com/',
        'http://europe.wsj.com/',
        'http://www.bbc.co.uk/',
        'http://nonexistant-subdomain.python.org/']

# 定义加载URL的函数
def load_url(url, timeout):
    # 使用urllib.request.urlopen打开URL并读取内容
    with urllib.request.urlopen(url, timeout=timeout) as conn:
        return conn.read()

# 使用ThreadPoolExecutor作为执行器,最大线程数为5
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
    # 启动下载任务,并将每个任务与对应的URL关联起来
    future_to_url = {executor.submit(load_url, url, 60): url for url in URLS}
    
    # 遍历已完成的Future对象
    for future in concurrent.futures.as_completed(future_to_url):
        url = future_to_url[future]
        try:
            # 获取任务的结果
            data = future.result()
        except Exception as exc:
            # 如果任务发生异常,则打印异常信息
            print('%r generated an exception: %s' % (url, exc))
        else:
            # 如果任务正常完成,则打印网页URL和内容的长度
            print('%r page is %d bytes' % (url, len(data)))

该程序使用concurrent.futures模块进行并发的网页下载。它创建了一个ThreadPoolExecutor执行器,最大线程数为5。然后,它遍历URL列表,使用executor.submit()方法提交下载任务,并将每个任务与对应的URL关联起来。

as_completed()函数中,它迭代已完成的Future对象,即已下载完成的任务。对于每个已完成的任务,它首先获取任务的结果(即网页内容),如果任务发生异常,则打印异常信息,否则打印网页的URL和内容的长度。

请注意,在运行该程序之前,请确保您的计算机已连接到互联网,以便能够成功下载网页内容。

3、模块函数

concurrent.futures模块除了提供ThreadPoolExecutor和ProcessPoolExecutor之外,还提供了一些其他的函数来执行异步任务和处理结果。以下是一些常用的concurrent.futures模块函数:

(1)concurrent.futures.as_completed(fs, timeout=None):

①接收一个可迭代的Future对象集合fs,返回一个生成器,在每个Future对象完成时产生结果。
②可选地指定timeout参数,用于限制等待结果的最长时间。
(2)concurrent.futures.wait(fs, timeout=None, return_when=ALL_COMPLETED):

①接收一个可迭代的Future对象集合fs,等待所有的Future对象完成。
②可选地指定timeout参数,用于限制等待结果的最长时间。
③可选地指定return_when参数,用于指定何时返回结果,可选值包括FIRST_COMPLETED、FIRST_EXCEPTION和ALL_COMPLETED。


这些函数提供了更灵活的方式来管理和处理Future对象的执行和结果。您可以根据需要选择适合的函数来处理异步任务。

以下是使用模块函数的示例:

import concurrent.futures

def task(n):
    return n ** 2

# 创建线程池执行器
with concurrent.futures.ThreadPoolExecutor() as executor:
    # 提交任务到线程池
    futures = [executor.submit(task, i) for i in range(5)]

    # 使用wait函数等待所有任务完成
    done, not_done = concurrent.futures.wait(futures, timeout=None)
    for future in done:
        result = future.result()
        print(result)

    # 使用as_completed函数按照完成顺序获取结果
    for future in concurrent.futures.as_completed(futures):
        result = future.result()
        print(result)

4、Executor 对象

concurrent.futures模块中的Executor是一个抽象基类,用于表示执行器对象。它定义了一些共同的方法和行为,用于管理并发执行的任务。但要通过它的子类调用,而不是直接调用。

Executor类并不直接实例化,而是通过具体的子类如ThreadPoolExecutorProcessPoolExecutor来创建实例。

以下是一些常用的Executor类方法:

(1)submit(fn, *args, **kwargs): 提交一个可调用对象和它的参数给执行器,返回一个Future对象,表示该任务的未来结果。

(2)map(fn, *iterables, timeout=None): 批量提交任务,并按原始迭代器的顺序返回结果。它类似于内置函数map(),但是可以异步地并发执行任务。

(3)shutdown(wait=True): 关闭执行器,不再接受新的任务。如果wait参数为True(默认值),则在所有任务完成后再关闭执行器。

(4)submit_to_executor(fn, executor, *args, **kwargs): 将任务提交给指定的执行器对象,并返回一个Future对象。

(5)map_to_executor(fn, executor, *iterables, timeout=None): 将任务批量提交给指定的执行器对象,并返回结果。

这些方法使得在执行任务时更加方便和灵活。可以根据具体的需求选择合适的方法和执行器类型。

5、Future 对象

concurrent.futures.Futureconcurrent.futures模块中的一个类,用于表示一个异步任务的未来结果。它将可调用对象封装为异步执行。Future 实例由 Executor.submit() 创建,除非测试,不应直接创建。

以下是concurrent.futures.Future的一些常用方法:

(1)result(): 等待并返回异步任务的结果。如果任务尚未完成,该方法会阻塞直到任务完成并返回结果。

(2)done(): 判断异步任务是否已经完成,返回布尔值。

(3)cancel(): 取消异步任务的执行。如果任务已经开始执行或已经完成,则无法取消。

(4)add_done_callback(fn): 添加一个回调函数,当异步任务完成时会调用该回调函数。文章来源地址https://www.toymoban.com/news/detail-488753.html

到了这里,关于python:并发编程(十三)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 半路出家自学当程序员这一年的经历,大家一起共勉

    2022年3月7日,我来到了上海。那是一个寒冷的夜晚。虽然因为提前找到了工作,心里还是比较踏实的。当时是我的牛马兄弟来接的我,然后我们住在了一起。这才使得我当时月薪4,000的人能够在上海得以生存。 来到上海没多久就出现了疫情,当时真的挺惨的。基本上一直是被

    2023年04月18日
    浏览(47)
  • 如何把aac转化为mp3?大家和我一起往下学习

        如何把aac转化为mp3?aac是一种先进的音频编码格式,通过较小的文件大小提供出色的音质体验。然而,由于其相对较少的普及度,与MP3相比,兼容性稍显不足,有些播放器可能无法直接识别aac格式。在某种程度上,我们可以将aac格式称为一种小众格式。考虑到这一点,一

    2024年02月11日
    浏览(25)
  • (三十三)补充Python经典面试题(吸收高级编程特性)

    这个函数定义有一个默认参数b,它的默认值是一个空列表[]。这道面试题涉及到Python中 函数参数默认值的一些重要概念和陷阱 。 首先,当你调用这个函数时,如果不传递参数b的值,它将使用默认的空列表[]。例如: 但是,这里有一个陷阱。默认参数b(即空列表[])在函数定

    2024年02月04日
    浏览(39)
  • python:并发编程(十六)

    本文将和大家一起探讨python并发编程的实际运用,会以一些我实际使用的案例,或者一些典型案例来分享。本文使用的案例是我实际使用的案例 (上篇) ,是基于之前效率不高的代码改写成并发编程的。让我们来看看改造的过程,这样就会对并发编程的高效率有个清晰地认

    2024年02月09日
    浏览(28)
  • python:并发编程(十二)

    本文将和大家一起探讨python的多协程并发编程 (下篇) ,使用内置基本库asyncio来实现并发,先通过官方来简单使用这个模块。先打好基础,能够有个基本的用法与认知,后续文章,我们再进行详细使用。 本文为python并发编程的第十二篇,上一篇文章地址如下: python:并发

    2024年02月09日
    浏览(24)
  • python并发编程

    多线程:threading,利用CPU和IO可以同时执行的原理,让CPU不会干巴巴等待IO完成; 多进程:multiprocess,利用多核CPU的能力,真正的并行执行任务; 异步IO:asyncio,当线程比较多时,切换线程也会占用CPU资源,可在单线程中利用CPU和IO同时执行的原理,实现函数异步执行; 使用

    2024年02月11日
    浏览(28)
  • python:并发编程(二十四)

    本文将和大家一起探讨python并发编程的实际项目:win图形界面应用 (篇六,共八篇) ,系列文章将会从零开始构建项目,并逐渐完善项目,最终将项目打造成适用于高并发场景的应用。 本文为python并发编程的第二十四篇,上一篇文章地址如下: python:并发编程(二十三)

    2024年02月11日
    浏览(28)
  • python:并发编程(九)

    本文将和大家一起探讨python的多线程并发编程 (下篇) ,使用内置基本库threading来实现并发,先通过官方来简单使用这个模块。先打好基础,能够有个基本的用法与认知,后续文章,我们再进行详细使用。 本文为python并发编程的第九篇,上一篇文章地址如下: python:并发编

    2024年02月09日
    浏览(25)
  • python:并发编程(十五)

    本文将和大家一起探讨python并发编程的第三方模块,他们都是一些高度集成的模块,可运用于特定的场景。也就是,如果期望在特定领域实现并发编程,可以不需要只依赖python的内置并发编程模块,可更加高效地实现并发编程。 本文为python并发编程的第十五篇,上一篇文章地

    2024年02月09日
    浏览(27)
  • python:并发编程(一)

    本文将和大家一起探讨并发编程,而不限于python语言。后续文章,我们将一起学习并发编程的相关模块。为什么专门写并发编程的文章呢?一个重要原因是有趣,而且实用。写一些简单的脚本可能很少用到并发编程,但是要提高这些脚本的工作效率,并发编程是个不错的选择

    2024年02月09日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包