python异步编程(1)——理论篇

1.理解多线程

当启动一个Python程序时,它会作为一个单独的进程运行在操作系统中。进程是操作系统分配资源(如内存和处理器时间)的基本单位。每个Python程序启动时,都会创建一个主线程。如果没有在代码中明确创建其他线程,那么程序中的所有操作都会在这个主线程中同步执行。

在单线程应用中,代码的执行是顺序和同步的。这意味着在任何给定时间点,程序中只有一部分代码在执行,直到它完成后,程序才会继续执行下一部分代码。

所以,如果需要同时执行多个任务,就可以通过创建额外的线程来实现。线程是进程内的执行单元,它们共享相同的内存空间,但可以并行执行不同的任务。在Python中,多线程通常用于I/O密集型任务,如文件操作、网络请求等。不过要注意的是,由于Python的全局解释器锁(GIL),在CPU密集型任务中使用多线程可能不会带来性能上的提升。在这种情况下,可以考虑使用多进程。

2.i/o密集 cpu密集和python多线程多进程

先明确它们是什么,有什么区别:

 I/O密集型(输入/输出密集型)任务是指那些主要时间花在I/O操作上的任务,如读写文件、网络通信、数据库操作等。在这类任务中,CPU的使用率通常不高,因为CPU大部分时间都在等待I/O操作的完成。

CPU密集型任务是指那些主要时间花在CPU计算上的任务,例如复杂的数学运算、图像处理等。这些任务需要大量的CPU时间来进行计算。

为什么CPU密集型的任务更适合多进程?为什么I/O密集型的任务更适合多线程?

答:

Python中有一个名为全局解释器锁(GIL)的机制,它阻止了多个线程同时执行Python字节码。因此,在多线程环境下,即使有多个CPU核心,也无法同时运行多个线程进行计算密集型任务。也就是说在CPU密集型任务的情况下,python的多线程是假的多线程。多进程可以在多核处理器上并行运行,每个进程运行在不同的CPU核上,从而实现真正的并行计算,避开了GIL的限制。

线程间共享内存和资源,切换线程的代价比切换进程低,这对于频繁的I/O操作来说非常有效率。当一个线程在等待I/O操作完成时,其他线程可以继续执行,从而更好地利用CPU。也就是说CPU是没有被用得很多(大部分情况下都是在等待),这也就不难解释python的多线程在I/O密集型任务的情况下,python的多线程是真的多线程。

3.并发和并行

并发是指多个任务在同一时间段内进行,但并不意味着它们在同一时刻执行。在单核处理器上,实际上并没有多个任务真正同时执行,而是通过任务间快速切换给人一种“同时运行”的错觉。这种情况适用于任务数多于CPU核心数的情况。

并行是指多个任务在同一时刻真正同时执行。这通常发生在多核处理器上,其中每个核心可以同时处理一个不同的任务。这种情况适用于当核心数多于或等于进程数时。

我们从多进程的角度来说明:电脑中如果你打开资源管理器,就能看到有几十个进程在运行,但是大多数电脑的核心都不会很多,所以多进程的本质是操作系统让得不同进程在核心上切换运行,在进程不活跃或者不需要进行计算的时候就切换出去来实现多进程

4.协程是什么?

协程(Coroutine)是一种计算机程序组件,它广泛用于实现异步编程。协程提供了一种比传统线程更轻量级的并发模型。

轻量级:协程比线程更轻量。它们不是由操作系统直接管理,而是在用户空间内进行调度,从而减少了上下文切换的开销。也就意味着创建和销毁协程的代价远低于线程。协程是在单个线程内调度的,因此不涉及线程切换的开销,也不会有多线程相关的锁竞争问题。

协程相比线程的优点:线程的创建需要占用大量的内存,也就是说当有成千上万的网络请求需要发送的时候,需要的线程数是相当大的,占用的内存也是相当大的;同时线程可能需要处理线程同步问题,如数据竞争和死锁,但是协程就不需要,它提供了更简洁的异步编程模型,尤其是在支持 async/await 语法的语言中(如python):

import asyncio
import aiohttp  # 需要安装 aiohttp 包async def fetch(session, url):async with session.get(url) as response:return await response.text()async def main():# 创建一个 aiohttp 的会话async with aiohttp.ClientSession() as session:urls = ["http://example.com", "http://example.org", "http://example.net"]tasks = []# 为每个 URL 创建一个任务for url in urls:task = asyncio.create_task(fetch(session, url))tasks.append(task)# 等待所有任务完成responses = await asyncio.gather(*tasks)# 输出结果for response in responses:print(response)# 运行主协程
asyncio.run(main())

fetch 是一个异步函数,它使用 aiohttp 库异步地获取给定 URL 的内容。

main 是另一个异步函数,它首先创建一个 aiohttp.ClientSession,然后为每个 URL 创建一个 fetch 协程的任务。

使用 asyncio.gather 同时运行所有的 fetch 任务,并等待它们全部完成。

最后,使用 asyncio.run(main()) 来运行 main 协程。

协程相比于线程的缺点:协程可能使得错误处理和调试变得更加复杂。协程的异步性质意味着堆栈跟踪可能不如同步代码那样直观,而且错误可能在程序的不同部分之间传播,使得定位问题变得更加困难。处理能力显然不如线程强大。

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

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

相关文章

【通讯录案例-沙盒路径 Objective-C语言】

一、接下来,我们来学习“存储”的相关的一些东西, 1.打开这个“数据存储“的ppt, 打开这个ppt, 首先呢,关于存储这一块儿, 存储呢,首先,有常见的几种方式,注意啊,这个里边儿是“方式”,方式,什么意思,是表示怎么去存,有五种方式: 1)XML属性列表(plist)归档:…

C++ 11新特性之语法甜点2

概述 C 11中引入了许多简化编程工作的语法上的新特性,我们暂且美其名曰:“语法甜点”。书接上篇,我们继续介绍C 11中的这些“语法甜点”,也是第二篇关于“语法甜点”的文章。 语法甜点6:模板右边双括号 在C 03中&#…

AOP使用案例

//加入bean Component //指定这是一个aop类 AspectSlf4j public class AOPlogin {Autowiredlogrizhi diaoyong;//获取传递过来jwt令牌AutowiredHttpServletRequest jwtlog ;//annotation(* com.example.tlias.AOPbao.loginin // Pointcut("annotation(* com.example.tl…

VUE!!!必看

ECMAScript 6-11 ECMAScript 相关介绍 什么是 ECMA ECMA(European Computer Manufacturers Association)中文名称为欧洲计算机制造商协会,这个组织的目标是评估、开发和认可电信和计算机标准。1994 年后该组织改名为 Ecma 国际。 什么是 …

【数据结构】(三)树Tree

目录 1、基本概念 2、二叉树Binary Tree 3、树、森林与二叉树的转换 4、赫夫曼树Huffman Tree与赫夫曼编码Huffman Coding 1、基本概念 (1)树(Tree)是 n(n ≥\geq 1)个节点的有限集,n 0时称…

记elasticsearch CPU负载100%问题

记elasticsearch CPU负载100%问题 环境:问题表现:初步排查:日志查询hot_thread 深入查询当前elasticsearch正在运行的Task查看Task详情解决问题对导致问题的原因的几个猜测问题复现:导致问题的原因。json导入规则问题json导入规则…

Linux系统安全之iptables防火墙

目录 一、iptables防火墙的基本介绍 1、netfile与iptables的关系 1.1netfile 1.2iptables 1.3iptables是基于内核的防火墙,其中内置了raw,mangle,nat和filter四个规则表 2、iptables防火墙默认规则表,链结构 二、iptables的…

python实例100第50例:使用 random 模块输出一个随机数。

题目:输出一个随机数。 程序分析:使用 random 模块。 程序源代码: 实例 #!/usr/bin/python # -*- coding: UTF-8 -*-import random#生成 10 到 20 之间的随机数 print (random.uniform(10, 20)) 以上实例输出结果为: 14.4012…

HashSet 的基本操作【集合容器知识回顾 ④】

HashSet 是 Java 中的一个集合类,它实现了 Set 接口。Set 是一种不允许包含重复元素的集合,而 HashSet 则是 Set 接口的一个具体实现。因此,HashSet 用于存储一组唯一的元素,不允许重复。 HashSet 的一些特点: 不允许…

漏洞03-CSRF漏洞

CSRF漏洞 文章目录 CSRF CSRF

mybatis之@Table和@Column注解

背景 假如我们使用mybatis有时候会看到Table和Column注解注解,Table通常写着表的名字,Column注解写着对应数据库字段的值,在一开始我以为它们是用来做数据库表和实体类映射的,比如说通过mybatis从数据库查询,然后结果…

链式二叉树(1)

目录 二叉树的概念&结构 二叉树的遍历概念 手写二叉树测试 二叉树遍历实现代码 递归图解 前序遍历递归图解 中序序遍历递归图解 后续遍历递归图解 二叉树的概念&结构 二叉树是: 空树非空:根节点,根节点的左子树、根节点的右子…

3ASC25H216A DATX132

3ASC25H216A DATX132 3ASC25H216A DATX132 3ASC25H216A DATX132在DAQ应用中使用非隔离DC/DC电源降压模块的优势 "... 图3:德州仪器电源模块电感HTS性能 此外,我们的电源 ... 响应。 图4:功率模块效率和负载瞬态响应 若保持 ...…

Java设计模式-组合模式(13)

大家好,我是馆长!今天开始我们讲的是结构型模式中的组合模式。老规矩,讲解之前再次熟悉下结构型模式包含:代理模式、适配器模式、桥接模式、装饰器模式、外观模式、享元模式、组合模式,共7种设计模式。 组合模式(Composite Pattern) 定义 组合(Composite)模式:又叫…

【开源】基于Qt5的ROS1/ROS2人机交互软件(支持地图编辑/多点导航)

本项目基于Qt5开发,基于CMake进行构建,可以实现一套代码同时在ROS1/ROS2系统中使用(本项目已接入CI,保证多ROS版本/系统版本可用性) 项目地址: https://github.com/chengyangkj/Ros_Qt5_Gui_App 软件在编译时会自动识别环境变量中的ROS1/ROS…

如何对视频进行翻译

下载视频和翻译软件 视频和翻译软件点击下载就行了,下载之后解压,然后把两个exe点一下。接下来如果资金充裕或者要求比较高的可以使用各个api,网站里有视频介绍了。 经济适用视频翻译 原理简析 首先这个软件对视频的翻译的流程大致如下&a…

2.4G SOC收发芯片XL2412P,适用于无线键鼠,遥控器等多种场景

XL2412P芯片是-款高性能低功耗的SOC集成无线收发芯片,集成MO核MCU,工作在2.400~2.483GHz世界通用ISM频段。该芯片集成了射频接收器、射频发射器、频率综合器、GFSK 调制器、GFSK解调器等功能模块,并且支持一对多线网和带ACK的通信模式。发射输出功率、工作频道以及通信数据率均…

C语言的预编译:加速编译过程和优化代码性能的关键步骤

概念 预编译是编译器在实际编译源代码之前执行的一个关键步骤。通过预编译,编译器可以在编译过程中进行必要的处理和优化,以提高编译速度和代码的执行性能。预编译阶段主要包括宏替换、头文件包含、条件编译等操作。本文将介绍预编译的基本概念和常用的…

【GameFramework框架】一、框架介绍

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 一、前言 【GameFramework框架】系列教程目录: https://blog…

本地socket通信

bilibili 就业班视频搬运 p55 1.作用 本地进程通信使用。 2. 类型 2.1 面向连接的,类似于TCP (但不是TCP 呀!这里不需要什么协议了!) socket函数的第二个参数填写 SOCK_STREAM int sfd socket(AF_UNIX, SOCK_…