记忆碎片之python线程池、submit()、done()、result()、wait()、as_completed()、map()方法

ThreadPoolExecutor的中的submit和FutureTask || 通过Executors 创建线程池的一些实例(Callable和Runnable的在其中的体现) 线程的创建方式,Callable接口和Future接口的配合,Runnable任务、Callable任务提交到线程池,他们之间的区别 阅读详情

大量注释,小白一看就懂的多线程及参数使用

threadpool已经不再是主流,但是对于任务数量不断增加的程序,每有一个任务就生成一个线程,最终会导致线程数量的失控,例如,整站爬虫,假设初始只有一个链接a,那么,这个时候只启动一个线程,运行之后,得到这个链接对应页面上的b,c,d,,,等等新的链接,作为新任务,这个时候,就要为这些新的链接生成新的线程,线程数量暴涨。在之后的运行中,线程数量还会不停的增加,完全无法控制。所以,对于任务数量不端增加的程序,固定线程数量的线程池是必要的。
相比threading,该模块通过submit返回的是一个future对象,它是一个未来可期的对象
通过它可以获悉线程的状态,主线程或者主进程中可以获取某一个线程或进程执行的状态或者某一个任务执行的状态及返回值
主线程可以获取某一个线程或者任务的状态,以及返回值
当一个线程完成的时候,主线程能够立即知晓
让多线程和多进程的编码接口一致

from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
import time


def spider(page):
    time.sleep(page)
    print(f"crawl task {page} finished")
    return page


# with ThreadPoolExecutor(max_workers=5) as t:  # 创建一个最大容纳量为5的线程池
#     task1 = t.submit(spider, 1)
#     task2 = t.submit(spider, 2)  # 通过submit提交执行的函数到线程池中
#     task3 = t.submit(spider, 3)
#
#     # 通过done来判断线程是否完成
#     print(f"task1: {task1.done()}")
#     print(f"task2: {task2.done()}")
#     print(f"task3: {task3.done()}")
#
#     time.sleep(2.5)
#
#     print(f"task1: {task1.done()}")
#     print(f"task2: {task2.done()}")
#     print(f"task3: {task3.done()}")
#     # 通过result()来获取返回值
#     print(task1.result())

# 使用with语句,通过ThreadPoolExecutor构造实例,
# 同时传入max_workers参数来设置线程池中最多能同时运行的线程数目

# 使用submit函数来提交线程需要执行的任务到线程池中,并返回该任务的句柄(类似文件、画图),
# 注意submit()不是阻塞的,而是立即返回的

# 通过使用done()方法判断该任务是否结束,提交任务后立即判断任务状态,显示都是未完成,在显示2.5秒后
# task1和task2执行完毕,task3仍然在执行中

# 使用result()方法可以获取任务的返回值

# 方法和参数
# wait(fs, timeout=None, return_when=All_COMPLETED)
# fs 表示需要执行的序列
# timeout 等待的最大时间,如果超过这个时间
# return_when 表示wait返回结果的结果,默认为ALLP_COMPLETED全部执行完成后再返回结果

from concurrent.futures import ThreadPoolExecutor, wait, FIRST_COMPLETED, ALL_COMPLETED


def spider2(page):
    time.sleep(page)
    print(f"crawl task {page} finished")
    return page


# with ThreadPoolExecutor(max_workers=5) as t:
#     all_task = [t.submit(spider2, page) for page in range(1, 5)]
#     # 返回条件 FIRST_COMPLETED 当第一个任务完成的时候就停止等待,继续主线程任务,所以紧接着打印了“结束”
#     wait(all_task, return_when=FIRST_COMPLETED)
#     print("结束")
#     # 设置延时(等待)时间2.5秒
#     print(wait(all_task, timeout=2.5))
#     # 所以最后只有task4还在运行

# as_completed
# 虽然使用return_when=FIRST_COMPLETED判断任务是否结束,但是不能在主线程中一直判断
# 最好的办法是当某个任务结束来,就给主线程返回结果,而不是一直判断每个任务是否结束
# as_completed就是当子线程中的任务执行完成后,直接用result()获取返回结果

from concurrent.futures import as_completed


def spider3(page):
    time.sleep(page)
    print(f"crawl task {page} finished")
    return page


def main():
    with ThreadPoolExecutor(max_workers=5) as t:
        obj_list = []
        for page in range(1, 5):
            obj = t.submit(spider3, page)
            obj_list.append(obj)
        for future in as_completed(obj_list):
            data = future.result()
            print(f"main:{data}")


# main()    使用过后发现,这个多线程比上面的测试耗时都多一些
# as_completed()方法是一个生成器,在没有任务完成的时候就会一直阻塞,除非设置了timeout
# 当某个任务完成的时候,会yield这个任务,就能执行for循环下面的语句,然后继续阻塞程序,直到所有任务结束
# 同时,先完成的任务会先返回给主线程

# map
# map(fn, *iterables, timeout=None)
# fn 需要线程执行的函数
# iterables 接收一个可迭代对象
# 和wait()的timeout一样,用于延时,但是map是返回线程执行的结果,如果timeout小于线程执行时间会抛出TimeoutError

def spider4(page):
    time.sleep(page)
    print(f"crawl task {page} finished")
    return page


def main2():
    executor = ThreadPoolExecutor(max_workers=4)
    i = 1
    # 列表中的每一个元素都执行来spider4()函数,并分配各线程池   task1:2
    for result in executor.map(spider4, [2, 3, 1, 4]):
        print(f"task{i}:{result}")
        i += 1


main2()
# 使用map方法,无需提前使用submit方法,与Python高阶函数map含义相同,都是将序列中的每个元素都执行同一个行数
# 与as_completed()方法的结果不同,输出顺序和列表的顺序相同,
# 就算1秒的任务执行完成,也会先打印前面提交的任务返回的结果

# map可以保证输出的顺序, submit输出的顺序是乱的
# 如果你要提交的任务的函数是一样的,就可以简化成map。但是假如提交的任务函数是不一样的,
# 或者执行的过程之可能出现异常(使用map执行过程中发现问题会直接抛出错误)就要用到submit()
# submit和map的参数是不同的,submit每次都需要提交一个目标函数和对应的参数,
# map只需要提交一次目标函数,目标函数的参数放在一个迭代器(列表,字典)里就可以。

python-17-并行计算和分布式计算框架dask 并行计算dask 阅读详情

相关推荐

Python并发编程双刃剑:submit()与map()方法深度抉择指南

submit()是瑞士军刀:灵活处理复杂场景,代价是更高的内存开销map()是流水线:高效处理批量数据,牺牲部分灵活性数据量级决定基础选择:万级以下随意,百万级优先map()结果顺序决定结构:需要顺序保障时别无选择异常密度决定错误处理策略:高异常率场景必用submit()通过合理运用这两个方法,您将能构建出既高效又健壮的并发系统。现在,是时候让您的代码在性能与可维护性之间找到完美平衡点了!

铭渊老黄 322

python 多线程submit的源码分析

submit def submit(self, fn, *args, **kwargs): with self._shutdown_lock: if self._broken: raise BrokenThreadPool(self._broken) if self._shutdown: raise Run...

luo_xinyu的博客 2763

【信息科学与工程学】计算机科学与自动化——第三百零四篇 高性能系统开发指南01

高并发:限流、熔断、降级高性能:红包拆分、多级缓存、大Key/热Key拆分、Pipeline、线程池、RocketMQ零丢失、幂等、分布式锁、集群缩容、分批入库海量数据处理:日志分表分片、跨表查询、冷热分层、大数据引擎服务器选型系统安全:网关安全、服务器安全、云存储安全、风控、监控、测试数据一致性:缓存与数据库一致性、大厂方案、蓝绿回滚、流量一致性、流程一致性项目与团队管理:流程问题、管理问题(风险、成本、人员、文档、培训)稳定性建设:上线三板斧、线上五步闭环、混沌工程、容量规划。

weixin_49199313的博客 248

python 获取线程返回值

以上方法都可以用于获取线程或进程的返回值,在实际使用时,根据具体的需求选择合适的方法。

qq_42629529的博客 4464

【信息科学与工程学】计算机科学与自动化——第八十一篇 Java分布式软件高并发/高可用算法01

4. 消息队列(如Kafka的Topic分区,本质是范围)。3. 若是ACCEPT事件,bossGroup线程接受连接,创建SocketChannel,并将其注册到workerGroup的一个EventLoop的Selector上,关注READ事件。1. 分布式缓存分片(如Redis Cluster)。4. 分布式文件存储(如Ceph CRUSH)。6. 调用栈的模拟(如协程)。3. 服务网格(如Istio)的基础。2. 本地缓存与集中式缓存(如Redis)的一致性维护。3. 静态数据(如配置)缓存。

weixin_49199313的博客 1220

【信息科学与工程学】计算机科学与自动化——第一百五十九篇 并行计算开发设计01

编号编程语言(含版本)+开发框架应用场景机制+用法+详细设计+详细配置编译器(版本+内核+底层机制+优化方法+阶段)底层实现·说明·缺陷+优势的·解决方案及数学建模引入版本国产化/信创/商用CPU/GPU/DPU芯片适配及指令集列表和指令调用和时序图关联知识&标准1高性能科学计算、深度学习训练与推理、图像处理、物理模拟、金融风险分析SIMT模型,kernel函数并行执行海量线程。用法:定义__global__

weixin_49199313的博客 246

Python ThreadPoolExecutor 实战指南:高效管理I/O并发任务

ThreadPoolExecutor 是 Python 标准库中用于管理线程生命周期的核心并发工具,其本质是将底层 threading 资源封装为高层 Executor 抽象,解决 I/O-bound 场景下的任务调度、异常传播、超时控制与资源回收等工程难题。相比手写 threading + Queue,它通过 Future 模型实现结果与异常的统一收口,显著提升代码健壮性与可维护性。技术价值体现在降低并发开发门槛、避免线程泄漏与静默异常,并支持生产级监控与熔断。典型应用场景包括 HTTP 请求批处理、文件

431

大象机器人myAGV移动机器人+mechArm六轴机械臂,开源复合机器人开发与实践!

我们这章节的内容是将协作性机械臂打破距离上的限制,跟移动机器人(myAGV)相连接,实现一个案例。

m0_71627844的博客 1487

Python入门到精通--高级语法

python文件操作有两种方式,第一种传统方式 先使用open函数打开文件,然后操作,最后关闭文件,如下: 可以看到已经顺利读取到了文本内容,但是呢,这种不是推荐写法,第二种才是推荐写法,使用with上下文管理工具 - 第二种使用上下文管理工具 with语句 使用with 来声明文件打开,这样就无需关心后续的文件关闭了,系统会自动帮我们关闭,如下:第二种使用with上下文管理工具,自动释放文件 这种方式有多个好处,可以同时打开多个文件,可以不用关心文件的关闭等,实例如下: 输出如下 后面都会使用with进

初心不忘、始终方得 211

ST7102驱动移植与调试实战

本文详细介绍了在君正T40平台上移植和调试ST7102 LCD驱动芯片的实战经验。内容涵盖硬件接口配置、时序参数调整、寄存器初始化序列编写及常见问题解决,重点解析了ST7102单芯片集成显示与触控功能的特性,为嵌入式设备显示驱动开发提供实用指南。

k6l7m8n9的博客 1406

ESP32-S3 SPI驱动SD卡与FATFS文件系统实践

SPI(串行外设接口)是嵌入式系统中常用的同步串行通信协议,通过主从架构实现全双工通信。其工作原理基于时钟同步和数据线传输,具有接线简单、占用引脚少的优势。在存储扩展场景中,SPI模式可驱动SD卡实现大容量数据存储,配合FATFS文件系统可提供标准化的文件管理能力。ESP32-S3作为乐鑫推出的高性能Wi-Fi/蓝牙双模芯片,其SPI外设支持高达80MHz时钟频率,结合ESP-IDF提供的sdspi_host驱动,开发者能快速实现SD卡存储方案。该技术广泛应用于物联网设备日志存储、传感器数据采集等场景,本实

weixin_29168393的博客 357

python学习笔记之多线程练习ThreadPoolExecutor,map,submit

主要练习了ThreadPoolExecutor,map和submit的区别,推荐使用submit更灵活。

紫微斗数象法奥义ZWDStudy 2263

LAN8720芯片硬件设计避坑指南:从晶振选择到PHY地址配置的5个关键细节

本文深入解析LAN8720以太网PHY芯片硬件设计的五个关键细节,涵盖晶振模式选择、PHY地址配置、复位电路设计、电源滤波与接口布线。重点阐述了REF_CLK Out与REF_CLK In两种时钟模式的配置逻辑与应用场景,提供了避免通信失败与信号完整性问题的实战方案,是嵌入式网络硬件开发的实用避坑指南。

i1j2k的博客 512

python线程池 ThreadPoolExecutor 使用记录

一、submit /result方法 submit 函数用来提交线程需要执行的函数和参数,submit函数是立即返回的,从print(task1)输出结果在print(f'get page {times} success') 输出结果之前可以得出 result 函数用来获取线程结果,该方法是阻塞的,从print(f'get page {times} success') 输出结果 在print(task2.result()) 之前输出 可以得出 import time def get_html(..

李俊的博客 2649

C#版OpenCV:OpenCVSharp 最详细最全面教程(万字详细总结)

OpenCVSharp 是一个用于 .NET 环境的 OpenCV 包装库,它提供了一种简便的方法来利用 OpenCV 的功能进行图像和视频处理。OpenCV(Open Source Computer Vision Library)是一个开源计算机视觉和机器学习软件库,最初由 Intel 研发并发布。OpenCVSharp 让 C# 和其他 .NET 语言的开发者可以方便地访问 OpenCV 的强大功能。// 打印 OpenCV 版本信息Cv2。

仰望星空的博客 2万+

深入理解SQL注入中的union select 1,2,3....

UNION 用于合并两个查询的结果集

渗透之路,攻防之间皆学问 2万+

python线程池提交任务

2. 方式提交 这种提交方式是一条一条地提交任务: 1. 可以提交不同的任务函数; 2. 线程池的线程在执行任务时出现异常,程序不会停止,而且也看不到对应的报错信息; 3. 得到的结果是乱序的。 3. 方式提交 这种提交方式可以分批次提交任务:

优快云1csdn1的博客 1512

fanuc机器人I/O分配

FANUC机器人在和其他外部设备进行通讯时,需要对信号进行配置。 在机器人处于UOP自动分配状态时,系统会自动检索已配对设备,并分配相应的机架号。 当我们需要手动对信号进行分配时,可参考以下机架号进行配置。 不同的通讯协议对应的机架号不同,外部通讯协议常用的机架号参考下表: 序号 机架号 通讯类型 1 0 Process I/O 2 1-15

haier123888的博客 1万+

python线程池及其原理和使用

系统启动一个新线程的成本是比较高的,因为它涉及与操作系统的交互。在这种情形下,使用线程池可以很好地提升性能,尤其是当程序中需要创建大量生存期很短暂的线程时,更应该考虑使用线程池。 线程池在系统启动时即创建大量空闲的线程,程序只要将一个函数提交给线程池,线程池就会启动一个空闲的线程来执行它。当该函数执行结束后,该线程并不会死亡,而是再次返回到线程池中变成空闲状态,等待执行下一个函数。 此外,使用线程...

whatday的专栏 7213

五十天精通硬件设计第6天-放大器知识及选型

运算放大器(Operational Amplifier,简称运放)是一种高增益的直流耦合差分放大器,广泛应用于信号处理、滤波、比较、积分、微分等电路中。

whm128的博客 592

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

【python高阶编程】python线程池简单应用

python线程池

Heney33的博客 5170

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

python 线程池ThreadPoolExecutor

每个线程各分配一个任务,剩下的任务排队等待,当某个线程完成了任务的时候,排队任务就可以安排给这个线程继续执行,免于停的创建和销毁线程,这就是所谓的线程池 ThreadPoolExecutor 原理。...

weixin_39451323的博客 3797

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

python 线程池使用

当线程池初始化时,会自动创建指定数量的线程,有任务到达时直接从线程池中取一个空闲线程来用即可,当任务执行结束时线程不会消亡而是直接进入空闲状态,继续等待下一个任务。而随着任务的增加线程池中的可用线程必将逐渐减少,当减少至零时,任务就需要等待了。在 python 中使用线程池有两种方式:一、是基于第三方库 threadpool二、是基于 python3 新引入的库 concurrent.futures.ThreadPoolExecutor。......

小胖_@的博客 9433

python基础-进程池、submit同异步调用、shutdown参数、ProcessPoolExecutor进程池、进程池ftp

引入进程池 使用ProcessPoolExecutor进程池 使用shutdown 使用submit同步调用 使用submit异步调用引入进程池在学习线程池之前,我们先看一个例子from multiprocessing import Process import time def task(name): print("name",name) time.sleep(1)if __n

全干工程师 2万+

Python 中的并发编程和异步编程

在程序中,如果有大量的 CPU bound 任务,或是有大量的 I/O bound 任务,则可以使用并发编程和异步编程,极大地提高代码的运行速度。

drin201312的博客 2154

python线程池ThreadPoolExecutor使用

假设我们必须多线程任务创建大量线程。由于线程太多,因此可能会有很多性能问题,这在计算上会是最昂贵的。一个主要问题可能是吞吐量受限。我们可以通过创建一个线程池来解决这个问题。一个线程池可以被定义为一组预先实例化和空闲的线程,它们随时可以开始工作。创建线程池比我们需要执行大量任务时为每个任务实例化新线程更受欢迎。线程池可以管理大量线程的并发执行,如下所示 -

如渊的博客 2653
上一篇: 记忆碎片之python多线程、线程安全、GIL锁、local()对象
下一篇: 《封号码罗》python爬虫之140行代码五步法破解字体反爬虫(五)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值