Python多线程Concurrent

背景

从 Python3.2 开始,标准库为我们提供了 concurrent.futures 模块,它提供了 ThreadPoolExecutorProcessPoolExecutor两个类,实现了对 threadingmultiprocessing 的进一步抽象(这里主要关注线程池),不仅可以自动调度线程,还可以做到:

  1. 主线程可以获取某一个线程(或者任务的)的状态,以及返回值。
  2. 当一个线程完成的时候,主线程能够立即知道。
  3. 让多线程和多进程的编码接口一致。

总结:实现更容易,效率更高

ThreadPoolExecutorProcessPoolExecutor实现 互换很便捷,搞懂一个即可

看到 Pool 单词,我们就能想到 这是一个 池子,池子的概念 是 大小是有上限的,满足最大的数值以后就开始排队

1. 线程池ThreadPoolExecutor

使用 ThreadPoolExecutor 来实例化线程池对象。传入max_workers参数来设置线程池中最多能同时运行的线程数目。

from concurrent.futures import ThreadPoolExecutorexecutor = ThreadPoolExecutor(max_workers=2)    # 表示在这个线程池中同时运行的线程有2个线程

2. 线程池Submit

使用 submit 函数来提交线程需要执行的任务(函数名和参数)到线程池中,并返回该任务的返回值,注意 submit() 不是阻塞的,而是立即返回,即无序返回。通过 submit 函数返回的任务句柄,能够使用 done() 方法判断任务是否结束,可以使用result() 方法获得返回值。

import concurrent.futuresexecutor = concurrent.futures.ThreadPoolExecutor(max_workers=2)def func(num):for i in range(num):time.sleep(1)return num * numtask = executor.submit(func, i)
print(future.done())

3. 线程池Cancel

使用 cancel() 方法可以取消提交的任务,如果任务已经在线程池中运行了,就取消不了。举个例子,线程池的大小设置为2,如果只有2个任务,那么任务已经在运行了,会取消失败。如果改变线程池的大小为1,那么先提交的是task1,task2还在排队等候,这是时候就可以成功取消。

import concurrent.futures
executor = concurrent.futures.ThreadPoolExecutor(max_workers=1)def func(num):for i in range(num):time.sleep(1)return num * numtask1 = executor.submit(func, i)
task2 = executor.submit(func, i)print(task1.done())
print(task2.cancel()) # 如果到这里task1没有完成,就会取消

4. 线程池As_completed()

按照上面的逻辑如果我们在线程完之后需要一个一个判断是否完成 是非常不合理的,as_completed() 方法可以一次取出所有任务的结果。as_completed() 方法是一个生成器,在没有任务完成的时候,会阻塞,在有某个任务完成的时候,会 yield这个任务,就能执行for循环下面的语句,然后继续阻塞住,循环到所有的任务结束。从结果也可以看出,先完成的任务会先进去到as_completed。

import concurrent.futures
import time
from concurrent.futures import as_completedfrom tqdm import trangeexecutor = concurrent.futures.ThreadPoolExecutor(max_workers=2)def func(num):for i in range(num):time.sleep(1)return num * numfuture = []
for i in range(8, -1, -1):print(i)start = time.time()future.append(executor.submit(func, i))print(time.time() - start)for ft in as_completed(future):print(ft.done())print(ft.result())

5. 线程池Map

map方法和2中submit方法是一样的功能,但是区别在于map返回出来的结果顺序与输入顺序,而submit是无序的,没有阻塞操作。

summit方法中args是按参数传输的,而map方法中args是一个List传输

import concurrent.futures
import time
from concurrent.futures import as_completedfrom tqdm import trangeexecutor = concurrent.futures.ThreadPoolExecutor(max_workers=2)def func(num):for i in range(num):time.sleep(1)return num * numfor data in executor.map(func, range(8, -1, -1)):print(data)

输出顺序一定是 88, 77, …11顺序,
但是用submit方法会先打印出7
7…

6. 线程池Wait

wait 方法可以让主线程阻塞,直到满足设定的要求。wait 方法接收3个参数,等待的任务序列、超时时间以及等待条件。等待条件 reture_when 默认为 ALL_COMPLETED,表明要等待所有的任务都结束。可以看到运行结果中,确实是所有任务都完成了,主线程才打印出 main。等待条件还可以设置为 FIRST_COMPLETED,表示第一个任务完成就停止等待。

from concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETED, FIRST_COMPLETEDexecutor = ThreadPoolExecutor(max_workers=2)
all_task = [executor.submit(get_html, (url)) for url in urls]
wait(all_task, return_when=ALL_COMPLETED)

总结:

  1. future的设计理念很棒,在线程池/进程池和携程中都存在future对象,是异步编程的核心。
  2. ThreadPoolExecutor 让线程的使用更加方便,减小了线程创建/销毁的资源损耗,无需考虑线程间的复杂同步,方便主线程与子线程的交互。
  3. 线程池的抽象程度很高,多线程和多进程的编码接口一致。

参考文章
https://blog.csdn.net/xiaoyu_wu/article/details/102820384

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STC89C52RC单片机设计的FM收音机+自动搜台+存储电台(程序+原理图+PCB)

资料下载地址&#xff1a;STC89C52RC单片机设计的FM收音机自动搜台存储电台&#xff08;程序原理图PCB) 1、实物图 2、部分程序 #include <reg52.h> #include "tea5767.h" #include "delay.h" #include "lcd1602.h" //K1:上一台 K2:下一…

mac电脑游戏推荐:NBA 2K24 街机版下载

NBA 2K24 街机版是一款由2K Sports开发并发行的篮球游戏&#xff0c;属于著名的NBA 2K系列。这款游戏为玩家提供了与NBA联赛中真实球员和球队互动的机会&#xff0c;体验篮球比赛的激情与紧张。街机版的NBA 2K24通常会在游戏厅、商场等公共场所设置&#xff0c;供玩家投币游玩。…

ubuntu server的安装

官网&#xff1a;https://ubuntu.com/ 点击 Get Ubuntu,选择Server&#xff0c;点击Get Ubuntu Server,下载iso到本地。 相关资料&#xff1a; Ubuntu Server 20.04详细安装教程虚拟机安装 Ubuntu

c++重载(运算符)

1&#xff09;C入门级小知识&#xff0c;分享给将要学习或者正在学习C开发的同学。 2&#xff09;内容属于原创&#xff0c;若转载&#xff0c;请说明出处。 3&#xff09;提供相关问题有偿答疑和支持。 对于系统的所有操作符&#xff0c;一般情况下&#xff0c;只支持基本数…

Android Gradle 开发与应用 (二): Android 项目结构与构建配置

目录 1. Android 项目的 Gradle 文件结构 1.1 项目根目录 1.2 模块目录 2. Gradle 构建配置详解 2.1 配置 Android 项目的 build.gradle 2.2 配置模块的 build.gradle 2.3 使用 productFlavors 管理多版本应用 2.4 使用 buildConfigField 注入构建常量 在 Android 开发…

AWTK 用 icon_at 属性设置图标位置

1. style 在 style 文件中通过 icon_at 属性设置图标位置。 <style name"right_bottom" icon_at"right_bottom"><normal icon"unchecked_right_bottom" /><pressed icon"unchecked_right_bottom" /><over i…

redis实战-短信登录

基于session的登录流程 session的登录流程图 1. 发送验证码 用户在提交手机号后&#xff0c;会校验手机号是否合法&#xff0c;如果不合法&#xff0c;则要求用户重新输入手机号 如果手机号合法&#xff0c;后台此时生成对应的验证码&#xff0c;同时将验证码进行保存&#x…

第2章:程序设计语言

第2章&#xff1a;程序设计语言 在源程序中&#xff0c;可由用户&#xff08;程序员&#xff09;为变量、函数和数据类型等命名。 脚本语言一般运行在解释器或虚拟机中&#xff0c;便于移植&#xff0c;开发效率较高。 变量是计算机内存单元的抽象&#xff0c;在程序中表示数据…

1186. 删除一次得到子数组最大和(leetcode)

1186. 删除一次得到子数组最大和&#xff08;leetcode&#xff09; 题目描述 给你一个整数数组&#xff0c;返回它的某个 非空 子数组&#xff08;连续元素&#xff09;在执行一次可选的删除操作后&#xff0c;所能得到的最大元素总和。换句话说&#xff0c;你可以从原数组中选…

第一节:如何开发第一个spring boot3.x项目(自学Spring boot 3.x的第一天)

大家好&#xff0c;我是网创有方&#xff0c;从今天开始&#xff0c;我会记录每篇我自学spring boot3.x的经验。只要我不偷懒&#xff0c;学完应该很快&#xff0c;哈哈&#xff0c;更新速度尽可能快&#xff0c;想和大佬们一块讨论&#xff0c;如果需要讨论的欢迎一起评论区留…

Pytorch实战(二)

文章目录 前言一、LeNet5原理1.1LeNet5网络结构1.2LeNet网络参数1.3LeNet5网络总结 二、AlexNext2.1AlexNet网络结构2.2AlexNet网络参数2.3Dropout操作2.4PCA图像增强2.5LRN正则化2.6AlexNet总结 三、实战3.1LeNet5模型搭建3.2模型训练 前言 参考原视频&#xff1a;哔哩哔哩。 …

kafka和rabbitmq的区别

1、语言与开发重点 1、Kafka&#xff1a;采用Scala语言开发&#xff0c;主要用于处理活跃的流式数据和大数据量的数据处理。 2、RabbitMQ&#xff1a;由Erlang语言开发&#xff0c;主要用在实时对可靠性要求比较高的消息传递上。 2、结构与交互方式&#xff1a; 1、Kafka&a…

Java中的WebSocket编程详解

Java中的WebSocket编程详解 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;在当今互联网应用中&#xff0c;实时通讯变得越来越重要&#xff0c;而WebSocket作为…

【后端面试题】【中间件】【NoSQL】ElasticSearch面试基本思路和高可用方案(限流、消息队列、协调节点、双集群)

基本思路 业务开发面试Elasticsearch的时候基本问的是基础知识以及倒排索引。 Elasticsearch最基本的可用性保障就是分片&#xff0c;而且是主从分片&#xff0c;所以遇到Elasticsearch如何做到高可用这个问题的时候&#xff0c;首先要提到这一点。 Elasticsearch高可用的核心…

【Android】ViewPage2嵌套Fragment+SeekBar横向滑动冲突

问题描述 ViewPage2嵌套FragmentSeekBar&#xff0c;拖动SeekBar的进度条时&#xff0c;触发ViewPage2的滑动。 解决方案&#xff1a; 方案一&#xff1a;通过事件总线ViewPage2的isUserInputEnabled属性 子Fragment&#xff1a; class SeekBarFragment : Fragment() {priv…

手机屏幕贴合项目(ni视觉如何找矩形的角坐标)

首先&#xff0c;我们存储了cg和dito感兴趣八个角图像的模板&#xff0c;用来匹配位置。 cover指的是cg的四个角模板&#xff0c;lcm是dito四个角匹配模板。 其次&#xff0c;我们采集的8副图像&#xff08;m_DlgCCDViewArr[2][4]&#xff09;中一定包含匹配模板的特征。 好&…

Json与Java类

简介 JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;易于人阅读和编写&#xff0c;同时也易于机器解析和生成。JSON数据由键值对构成&#xff0c;并以易于阅读的文本形式展现&#xff0c;支持数组、对象、字符串、数字、布尔值…

笔灵AI写作:释放创意,提升写作效率的秘诀

内容为王&#xff0c;在内容创作的世界中尤为重要。然而&#xff0c;面对写作时常常感到无从下手&#xff1a;有时缺乏灵感&#xff0c;有时难以表达清楚自己的想法。AI写作助手的出现&#xff0c;为这些问题提供了创新的解决方案&#xff0c;极大地改变了内容创作的过程。 今…

微调和rag的区别?

微调和RAG&#xff08;Retrieval-Augmented Generation&#xff09;在多个维度上存在显著的区别。以下是它们之间的主要差异&#xff1a; 1. **知识维度**&#xff1a; - RAG对知识的更新时间和经济成本更低。它不需要训练&#xff0c;只需要更新数据库即可。 - RAG对知识的掌控…

Pytest+Allure+Yaml+Jenkins+Gitlab接口自动化中Jenkins配置

一、背景 Jenkins&#xff08;本地宿主机搭建&#xff09; 拉取GitLab(服务器)代码到在Jenkins工作空间本地运行并生成Allure测试报告 二、框架改动点 框架主运行程序需要先注释掉运行代码&#xff08;可不改&#xff0c;如果运行报allure找不到就直接注释掉&#xff09; …