首页 > 其他分享 >ThreadPoolExecutor使用浅谈

ThreadPoolExecutor使用浅谈

时间:2023-11-01 22:58:01浏览次数:33  
标签:浅谈 futures 获取 任务 Future 线程 result 使用 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类创建一个线程池对象。可以指定线程池的大小(即可同时运行的线程数量),也可以使用默认值(大小为系统默认的处理器数量)。

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对象,表示异步执行的结果。

def my_task(arg):
    # 执行任务的代码
    return result

# 提交任务到线程池
future = executor.submit(my_task, arg)

获取任务结果

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

# 获取任务的结果
result = future.result()

获取一组任务结果

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

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()方法接受一个可调用对象和一个可迭代的参数列表,然后并行地对参数列表中的每个参数调用可调用对象,并返回一个迭代器,用于获取每个任务的结果。

def my_task(arg):
    # 执行任务的代码
    return result

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

# 批量提交任务并获取结果
results = executor.map(my_task, args)

等待任务完成

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

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()方法关闭线程池。关闭线程池后,将不再接受新的任务提交,但会等待已提交的任务完成。

# 关闭线程池
executor.shutdown()

  

标签:浅谈,futures,获取,任务,Future,线程,result,使用,ThreadPoolExecutor
From: https://www.cnblogs.com/beyond-tester/p/17804328.html

相关文章

  • Python JSON 使用指南:解析和转换数据
    JSON是一种用于存储和交换数据的语法。JSON是文本,使用JavaScript对象表示法编写。Python中的JSONPython有一个内置的json包,可用于处理JSON数据。示例:导入json模块:importjson解析JSON-从JSON转换为Python如果您有一个JSON字符串,可以使用json.loads()......
  • iotdb时序数据库常见使用命令
    docker安装IOTDB核心代码:#docker启动dockerrun-d-p6667:6667-p31999:31999-p8181:8181--namesome-iotdbapache/iotdb#进入容器dockerexec-itsome-iotdb/bin/bash#执行命令,连接IotDBstart-cli.sh默认用户名和密码是:root/root 基本操作:#连接sbin......
  • Python JSON 使用指南:解析和转换数据
    JSON是一种用于存储和交换数据的语法。JSON是文本,使用JavaScript对象表示法编写。Python中的JSONPython有一个内置的json包,可用于处理JSON数据。示例:导入json模块:importjson解析JSON-从JSON转换为Python如果您有一个JSON字符串,可以使用json.loads()......
  • 探索在openebs中使用lvm做持久化
    1.部署官网:https://openebs.iolvm项目地址:https://github.com/openebs/lvm-localpv1.1.本地创建vgaptinstalllvm2-ylsblk#创建pv和vgsudopvcreate/dev/loop0sudovgcreatelvmvg/dev/loop0注意:这里根据自己需求看是否全部的node节点都需要使用lvm做本地存储,也可......
  • 使用Xtrabakcup工具实现增量、全量备份
    xtrabackup备份对比mysqldump,好处是:备份速度快,不锁表,支持增量备份。1、下载合适的包并安装官网下载地址:https://www.percona.com/downloads/Percona-XtraBackup-LATEST/在这里,我下载8.0.29wgethttps://downloads.percona.com/downloads/Percona-XtraBackup-LATEST/Percona-XtraBac......
  • .NET6 使用AutoMapper
    .NET6使用AutoMapper 一、Net6环境下的.netcore项目里如何使用AutoMapper实现依赖注入。注:AutoMapper是一个对象-对象映射器,可以将一个对象映射到另一个对象。第一步,在Nuget引入AutoMapper、AutoMapper.Extensions.DependencyInjection这两个NuGet包  ......
  • 飞腾派使用内核态编程完成LED20控制操作
    1基础知识在该程序设计过程中我们首先需要学习如何在内核态编程。1.1内核态编程在内核态中编写C语言程序和在用户态中编写C语言程序不同,在用户态中编写C语言程序,我们可以使用libc库,通过系统调用访问内核态的相关操作。基础的内核态程序如下:#include<linux/init.h>#include......
  • matlab中polyfit和polyval的使用(曲线拟合/多项式拟合/指数拟合)
    matlab中polyfit函数的作用是对数据进行数据拟合有些小伙伴可能搞不清楚polyfit和polyval之间的区别,这里就直接上我的笔记给大家看看吧%%普通的多项式拟合clear;clc;num=30;x=linspace(0,5,num);%横轴数据error=rand(1,num);%生产误差值a=x.^2+2*error;%......
  • SSL证书链及使用
    什么是证书链证书链简单来说是域名钥证书、CA公钥、根证书形成的一个颁发链条,属于公钥的一部分。更白话一点,就是证书链文件包含一系列CA机构公钥的证书。证书链格式一般证书链格式是.chain,证书定义顺序是倒序的,即先权威CA再根CA。以根CA+一个权威CA举例:-----BEGINCERTIFICA......
  • 关于LateX的使用
    安装方法https://zhuanlan.zhihu.com/p/493412905视频教程https://www.bilibili.com/video/BV11h41127FD一份不太简短得LateX教程(参考手册)https://github.com/CTeX-org/lshort-zh-cn/blob/master/README-zh.md笔记命令形式以\开头,末尾以{}结束,括号中代表命令参数由......