ThreadPoolExecutor使用浅谈

1. 基础介绍

ThreadPoolExecutor是Python标准库concurrent.futures模块中的一个类,用于实现线程池的功能。

ThreadPoolExecutor模块相比于threading等模块,通过submit方法返回的是一个Future对象,它代表了一个未来可期的结果。通过Future对象,我们可以在主线程(或主进程)中获取某个线程(或任务)的状态以及返回值,实现了多线程和多进程编码接口的一致性。

具体来说,Future对象具有以下特点:

  1. 获取状态和返回值:通过result()方法可以获取一个任务的执行结果。如果任务尚未完成,调用result()方法会阻塞主线程,直到任务完成并返回结果。

  2. 异步通知:当一个线程完成时,主线程可以立即得到通知。可以通过done()方法判断任务是否已完成,或使用add_done_callback()方法注册一个回调函数,在任务完成时自动调用该函数。

  3. 异常处理:如果任务抛出异常,Future对象会将异常抛出到主线程。可以使用exception()方法获取异常对象。

通过返回Future对象,我们可以更方便地管理和控制线程池中的任务。可以在主线程中获取任务的状态、返回值和异常信息,避免了线程之间的显式同步和等待。

总的来说,ThreadPoolExecutor模块提供了一种高级的多线程编程接口,使得多线程编程更加简洁和易用。它实现了多线程和多进程的编码接口一致性,使得我们可以使用类似的方式处理多线程和多进程编程任务。

2. 基础使用

创建线程池对象

可以使用ThreadPoolExecutor类创建一个线程池对象。可以指定线程池的大小(即可同时运行的线程数量),也可以使用默认值(大小为系统默认的处理器数量)。

1

2

3

4

5

6

7

8

9

from concurrent.futures import ThreadPoolExecutor

import time

  

def get_html(times):

    time.sleep(times)

    print("get page {} success".format(times))

    return times

  

executor = ThreadPoolExecutor(max_workers=2)    # 表示在这个线程池中同时运行的线程有3个线程

提交任务

使用submit()方法向线程池提交任务,该方法接受一个可调用对象(函数、方法等)作为参数,并返回一个Future对象,表示异步执行的结果。

1

2

3

4

5

6

def my_task(arg):

    # 执行任务的代码

    return result

# 提交任务到线程池

future = executor.submit(my_task, arg)

获取任务结果

可以使用Future对象的result()方法来获取任务的结果。如果任务尚未完成,result()方法会阻塞当前线程,直到任务完成并返回结果。

1

2

# 获取任务的结果

result = future.result()

获取一组任务结果

使用submit()方法向线程池提交一组任务,并获取返回的Future对象列表,使用as_completed()函数迭代处理Future对象列表,它会在任务完成时产生结果。可以使用next()函数或直接使用for循环来获取结果

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

def my_task(arg):

    # 执行任务的代码

    return result

args = [arg1, arg2, arg3, ...]

futures = [executor.submit(my_task, arg) for arg in args]

# 使用next()函数获取每个任务的结果

for future in as_completed(futures):

    result = future.result()

    # 处理任务结果

# 或者使用for循环获取每个任务的结果

for future in as_completed(futures):

    result = future.result()

    # 处理任务结果

批量提交任务

除了逐个提交任务,还可以使用map()方法批量提交任务。map()方法接受一个可调用对象和一个可迭代的参数列表,然后并行地对参数列表中的每个参数调用可调用对象,并返回一个迭代器,用于获取每个任务的结果。

1

2

3

4

5

6

7

8

def my_task(arg):

    # 执行任务的代码

    return result

args = [arg1, arg2, arg3, ...]

# 批量提交任务并获取结果

results = executor.map(my_task, args)

等待任务完成

使用wait()方法等待所有已提交的任务完成。可以指定超时时间,如果超时时间到达而还有任务未完成,则不再等待并返回结果。

1

2

3

4

5

6

7

8

9

10

from concurrent.futures import ALL_COMPLETED, FIRST_COMPLETED

# 等待所有任务完成

executor.wait(futures)

# 等待任意任务完成

executor.wait(futures, return_when=FIRST_COMPLETED)

# 等待所有任务完成或达到超时时间(单位为秒)

executor.wait(futures, timeout=10)

wait()方法接受三个参数:

  • fs:要等待的Future对象列表。
  • timeout:可选参数,指定等待的超时时间(单位为秒)。如果超时时间到达而还有任务未完成,则不再等待并返回结果。
  • return_when:可选参数,指定返回结果的条件。默认为ALL_COMPLETED,表示等待所有任务完成;也可以指定为FIRST_COMPLETED,表示等待任意一个任务完成。

关闭线程池

在不再需要线程池时,应该调用shutdown()方法关闭线程池。关闭线程池后,将不再接受新的任务提交,但会等待已提交的任务完成。

1

2

# 关闭线程池

executor.shutdown()

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/272509.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一文教你如何绕过统一认证拿到赏金

1.漏洞背景 统一认证通常是一种安全措施,用于验证用户的身份,以确保只有授权的用户才能访问敏感或受限的信息和服务。 当你尝试访问某个需要特定权限的网站或服务时,系统会将你重定向到一个统一认证页面。在这里,你需要输入你的登…

【鸿蒙应用ArkTS开发系列】- 沉浸式状态栏实现

文章目录 一、前言二、封装沉浸式状态栏管理类1、创建Demo工程2、封装状态栏管理类 三、编写页面实现沉浸式状态栏效果1、存储windowStage实例2、Page页面中实现沉浸式开启关闭功能2.1、开启沉浸式状态栏2.2、设置标题栏偏移量 一、前言 在应用开发中,页面跟状态栏…

Java代码审计鉴权漏洞InterceptorFilterShiroJWT(非常详细!!)

目录 0x00 前言 0x01 鉴权方式&审计思路 1、目前主流的鉴权方式 2、鉴权漏洞审计思路 0x02 Interceptor鉴权审计 - NewbeeMall电商系统 1、项目介绍 - NewbeeMall 2、Interceptor 补充介绍 3、NewbeeMall - Interceptor鉴权 - 代码审计 0x03 Filter鉴权审计 - 华…

PostGIS学习教程十五:几何图形的有效性

PostGIS学习教程十五:几何图形的有效性 在90%的情况下,“为什么我的查询给了我一个’TopologyException’错误"的问题的答案是"一个或多个输入的几何图形是无效的”,这就引出了这样一个问题:几何图形"无效"是什么意思&a…

JAVA复习三——CH5 Java Collection 、CH6 MultiThread

CH5 Java Collection(集合) 5.1 Java集合框架(位于java.util包中) 图一 集合框架图 从上面的集合框架图可以看到,Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集…

pytest分布式执行插件 pytest-xdist 的高级用法

想要使用多个CPU核心来进行测试,可以使用 -n 参数( 或者 --numprocesses) (使用8个核心来跑测试用例) 1 pytest -n 8 使用 -n auto 参数可以利用电脑的所有核心来跑测试用例 测试时使用的算法可以根据--dist命令参数定制: --dist load(默认选项)&…

手拉手Springboot整合JWT

环境介绍 技术栈 springbootmybatis-plusmysqljava-jwt 软件 版本 mysql 8 IDEA IntelliJ IDEA 2022.2.1 JDK 1.8 Spring Boot 2.7.13 mybatis-plus 3.5.3.2 Json Web令牌简称JWT Token是在服务端产生的一串字符串是客户端访问资源接口(AP)时所需要的资源凭证。…

【多省市译协盖章】2023年第九届中西部外语翻译大赛

“由中西部翻译协会共同体指导发起,各省市译协共建学术指导委员会,2023年第九届中西部外语翻译大赛由中西部翻译协会共同体秘书处(武汉公仪网络科技有限公司)承办。” (证书样图) 证书盖章单位&#xff1…

文件重命名:特殊符号影响你找文件吗?来看看这个解决方法

在日常生活和工作中,电脑已经成为必不可少的工具,而文件管理也是一项重要的任务。有时候遇到文件重命名的问题,例如当文件名中包含特殊符号时,这可能会给工作带来很大的困扰。当尝试寻找一个文件时,却发现因为文件名中…

Linux的账号及权限管理

一.管理用户账号 1.1 用户账户的分类 1.1.1 用户账号的分类 超级用户:(拥有至高无上的权利) root用户是Linux操作系统中默认的超级用户账号,对本主机拥有最高的权限,系统中超级用户是唯一的。普通用户: …

c++学习笔记(6)-类型转换

1、概念 C类型转换是将一种数据类型转换为另一种数据类型的过程。 2、分类 C中的类型转换可以从3个角度来划分: 根据类型转换是由程序员显式指定,还是由编译器自动完成,分为显式类型转换和隐式类型转换;根据参与类型转换的变量…

智能优化算法应用:基于减法平均算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于减法平均算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于减法平均算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.减法平均算法4.实验参数设定5.算法结果6.…

测试用例要如何写

​ 📢专注于分享软件测试干货内容,欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!📢交流讨论:欢迎加入我们一起学习!📢资源分享:耗时200小时精选的「软件测试…

IDEA基本设置

本博客适用于纯新手小白,或者刚下载IDEA想要优化开发添加配置的读者。 基础设置 不区分大小写代码补全 打开 IntelliJ IDEA。转到 “File”(文件) > “Settings”(设置)(Windows/Linux)或 “…

swagger1.2 apiPost工具测试接口没有问题,换成swagger 接口调测时报错 Required request body is missing

把 请求方法由get换成post GetMapping换成 PostMapping 原因apiPost自动把请求json参数封装到请求体里了, 但swagger没有封装,通过networker可以看到载荷里并没有任何东西

(C++)DS哈希查找—二次探测再散列(附思路和详细注释)

Description 定义哈希函数为H(key) key%11。输入表长(大于、等于11),输入关键字集合,用二次探测再散列构建哈希表,并查找给定关键字。 Input 测试数据组数 1≤�≤50. 每组测试数据格式如下&#xff1a…

面试题:Zabbix 和 Prometheus 到底怎么选?

文章目录 前言历史简介PrometheusZabbix 架构对比PrometheusZabbix 综合对比总结 前言 新公司要上监控,面试提到了 Prometheus 是公司需要的监控解决方案,我当然是选择跟风了。 之前主要做的是 Zabbix,既然公司需要 Prometheus,…

【如何破坏单例模式(详解)】

✅如何破坏单例模式 💡典型解析✅拓展知识仓✅反射破坏单例✅反序列化破坏单例✅ObjectlnputStream ✅总结✅如何避免单例被破坏✅ 避免反射破坏单例✅ 避免反序列化破坏单例 💡典型解析 单例模式主要是通过把一个类的构造方法私有化,来避免重…

鸿蒙系统的分布式技术:重塑智能终端的未来

华为鸿蒙系统自发布以来,凭借其创新的分布式技术,改变了我们对智能终端的认知和使用方式。鸿蒙系统的分布式技术是一种全新的设计理念,它将不同设备、不同应用场景视为一个整体,通过共享、协同和无缝连接,为用户带来前…

android setText不生效问题

1.直接说解决方案: 在代码没问题的情况下,将你的TextView的Id改一下,然后再重启编译器即可(注意,不修改TextView的ID,单独重启是没有作用的!) 2.出现问题的过程: 产品新增一个需求&#xff0c…