python5:基于多进程的并发编程、基于协程的并发编程的学习笔记

进程

  • 为什么要使用多进程?——GIL的存在,多线程实际不是并发执行
    将任务分为两类:
  • IO密集型(多线程)
  • CPU密集型(多进程)

多进程的基本用法

concurrent.futures.process.ProcessPoolExecutor#进程池 (与线程池用法一致
multiprocessing.Pool#单个进程
multiprocessing.Pool #进程池

可直接学习复习该链接:https://blog.csdn.net/ifhuke/article/details/128642625
有进程间通信,进程池
在这里插入图片描述

创建进程

委托操作系统创建,但不同操作系统创建进程的方式不一样

  • linux:fork:从父进程中继承内存(从运行了一半的程序中裂变出去)
  • windows:spawn:重新运行Python程序(1. 启动python程序; 2.import代码文件
  • 在这里插入图片描述
  • 在这里插入图片描述

协程

一种用户态的上下文切换技术(通过一个线程实现代码块间的相互切换执行,在一个协程中,遇到io等待时间,可以利用这个等待时间去做其他事情
yield就是一个协程思想的实现

yield、yield from

yield可以将函数变成生成器
在函数中加yield关键字,调用它,就会返回一个生成器
在这里插入图片描述
生成器的目的不是为了将代码打包,目的是为了生产或者返回一些值
1 创造生成器
2 通过next获取下一个值(可以理解为next去取yield的值)
3 如果遇到了StopIteration,说明内容生成结束
以上的用法,也叫做迭代器协议,就是不断从中去取内容,可以被for去使用
在这里插入图片描述
通过yield可以改变程序执行顺序,因此协程也称之为“用户态的线程”或“微线程”,即程序执行顺序是受用户控制的。
在Python中,协程是基于单线程的。
Tornado是一个Web开发框架,内部使用协程提供高并发

在这里插入图片描述
通过主线程去调度,即从g2中获得i,给到g3,再得到值,改进这个情况,引入yield from
在这里插入图片描述

yield是将生成器作为结果返回,yield from是把生成器的结果作为结果返回。但后来不用这个写法了,就先pass

协程的相关概念

  • 协程函数:定义为async def的函数
  • 协程对象:调用协程函数返回的对象
  • 事件循环:event loop 并发执行任务的大脑,判断哪些任务已处于可执行状态,并执行(循环只是主线程不断从事件队列里面取值/函数的过程)
  • 协程任务:rask 事件循环调度的最小单位,可由协程对象转化

关键字概述

  • async 定义函数时加上async,则该函数为协程函数
  • await 后面是一个可等待对象,如协程对象,协程任务---->去运行这个函数,运行完再继续fanhui
  • asyncio编写并发代码的库
  • run运行最高层级的入口点
  • asyncio.create_task() 创建task对象
import asyncio
import time
async def async_test(delay:int,content):await asyncio.sleep(delay)print(content)async def main():task_lady = asyncio.create_task(async_test(1,"lady"))#创建tasktask_killer = asyncio.create_task(async_test(2,"killer9"))await task_killer#可以await所有任务,如果只await了耗时短的,那么其他任务没有完成就结束了if __name__ == '__main__':print(f"start at {time.strftime('%X')}")asyncio.run(main())print(f"end at {time.strftime('%X')}")
  • gather 接收列表,结果是一个由所有返回值聚合而成的列表。结果值得顺序与was

生成器如何使用协程

借助工具实现协程,在这些工具中,使用yield关键字

  • Tornado提供了各种协程版的函数
  • 使用gevent的猴子补丁,可以不使用协程的写法,但是有协程的开发效果

asyncio模块

用来编写并发代码的酷,被用作多个提供高性能Python异步框架的基础,包括网络和网站服务,数据库链接库,分布式任务队列等,asyncio往往是构建IO密集型和高层级 结构化 网络代码的最佳选择

import time
import asyncioasync def f1():time.sleep(1)#这是线程阻塞的代码  整个线程会停住一秒print("f1:done")async def f2():time.sleep(1)#这是线程阻塞的代码print("f2:done")async def main():await f1();await f2();if __name__ == "__main__":time = time.time();asyncio.run(main());#入口time2 = time.time();print(f"耗时{time2-time:.2f} ");

耗时2s

用asyncio后改变的代码:

import time
import asyncioasync def f1():await asyncio.sleep(1)#这是非阻塞的协程 ,类似于yeildprint("f1:done")async def f2():asyncio.sleep(1)#非阻塞的协程 ,类似于yeildprint("f2:done")async def main():await f1();#等待协程结束await f2();

依然2s,依旧不是并行运行的,需要用到
在这里插入图片描述
修改代码:

async def main():await asyncio.gather(f1(),f2());

修改后,耗时1s,是并发操作
所以在异步编程中,如果有一处代码写成了同步,则整个代码都同步。
所以,像锁,sleep,迭代,队列,网络请求(socket)等都需要用异步资源
注意很多的第三方模块都是同步的,所以我们需要确定是“异步”的第三方库 https://github.com/aio-libs

async 和 await

创建协程的方式有两种,一种是yield关键字,一种是async关键字,我们一般用后者
定义函数时,加上async修饰,即async def func(),则该函数为协程函数,协程函数返回的对象即为协程对象

await后面是一个可等待对象,如协程对象,协程任务,用于告诉eventloop在此协程中需要等待后面的函数运行完成后才能继续(即执行下一个协程),运行完成后返回结果

新的协程如何运行
  • 在其他协程中被await
  • 使用asyncio模块提供第一个协程的运行
async def f_3():print("f3 doing")await f_4()#等f4async def f_4():print("f4 doing")if __name__=="__main__":asyncio.run(f_3())#第一个协程的运行

或者使用task方法执行协程

在这里插入图片描述

并发方案的选择

1 分布式,还是单击

  • 分布式,只能选择多进程

2 CPU密集,还是IO密集

  • CPU密集,多进程

3 单击IO密集型,并发数多不多

  • 如果不多,多线程(推荐)
  • 如果多,协程
  • 如果特别多:多进程+多线程+协程

4 是否有动态调度

  • 没有, 线程池
  • 有,手动创建线程

并发任务之间的通信:队列
并发任务之间的同步:锁

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

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

相关文章

程序员35岁会失业吗?‍

程序员35岁会失业吗?👨‍💻🕒 程序员35岁会失业吗?👨‍💻🕒摘要引言技术更新与个人适应性持续学习的重要性实用学习方法 职业发展路径多样性职业转型的机会实践案例分享 企业文化与就…

【SpringBoot】如何定义接口

定义get接口 使用GetMapping定义一个基本get接口 RestController //表示定义一个json格式返回给前端 public class test {private Map<String,Object> map new HashMap<>();GetMapping(value "/test") //定义接口路径public Object userInfo(Strin…

代码随想录训练营Day32:● 122.买卖股票的最佳时机II ● 55. 跳跃游戏 ● 45.跳跃游戏II

122.买卖股票的最佳时机II 题目链接 https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/description/ 题目描述 思路 看完视频讲解之后豁然开朗啊简直了&#xff01;&#xff01;&#xff01; 统计后一天减去前一天&#xff0c;差值为正数的&#xff0c;再…

图论基础|417. 太平洋大西洋水流问题、827.最大人工岛、127. 单词接龙

目录 417. 太平洋大西洋水流问题 827.最大人工岛 127. 单词接龙 417. 太平洋大西洋水流问题 题目链接(opens new window) 有一个 m n 的矩形岛屿&#xff0c;与 太平洋 和 大西洋 相邻。 “太平洋” 处于大陆的左边界和上边界&#xff0c;而 “大西洋” 处于大陆的右边界…

css的active事件在手机端不生效的解决方法

需求&#xff1a;需求就是实现点击图中的 “抽奖” 按钮&#xff0c;实现一个按钮Q弹的放大缩小动画 上面是实现的效果&#xff0c;pc端&#xff0c;点击触发 :active 问题&#xff1a;但是这种方式在模拟器上可以&#xff0c;真机H5一调试就没生效了&#xff0c;下面是简单…

数据结构·二叉树(1)

目录 1 树的概念及结构 1.1 树的结构 1.2 树的概念 1.3树的表示 2 二叉树的概念及结构 2.1二叉树的概念 2.2 特殊的二叉树 2.3 二叉树的存储结构 1 树的概念及结构 1.1 树的结构 前面所学到的顺序表链表等&#xff0c;都是线性的数据结构&#xff0c;今天介绍的树&am…

电脑卸载软件怎么清理干净?电脑清理的5种方法

随着我们在电脑上安装和卸载各种软件&#xff0c;很多时候我们会发现&#xff0c;即使软件被卸载&#xff0c;其残留的文件和注册表项仍然存在于电脑中&#xff0c;这不仅占用了宝贵的磁盘空间&#xff0c;还可能影响电脑的性能。那么&#xff0c;如何确保在卸载软件时能够彻底…

mysql - 缓存

缓存 InnoDB存储引擎在处理客户端的请求时&#xff0c;当需要访问某个页的数据时&#xff0c;就会把完整的页的数据全部加载到内存中&#xff0c;也就是说即使我们只需要访问一个页的一条记录&#xff0c;那也需要先把整个页的数据加载到内存中。将整个页加载到内存中后就可以…

计算机三级——网络技术(综合题第五题)

第一题 填写路由器RG的路由表项①至④。 目的网络&#xff0f;掩码长度输出端口输出端口172.19.63.192&#xff0f;30S0(直接连接)172.19.63.188&#xff0f;30S1(直接连接) 路由器RG的S0的IP地址是172.19.63.193&#xff0c;路由器RE的S0的IP地址是172.19.63.194。 【解析】…

VPCFormer:一个基于transformer的多视角指静脉识别模型和一个新基准

文章目录 VPCFormer:一个基于transformer的多视角指静脉识别模型和一个新基准总结摘要介绍相关工作单视角指静脉识别多视角指静脉识别Transformer 数据库基本信息 方法总体结构静脉掩膜生成VPC编码器视角内相关性的提取视角间相关关系提取输出融合IFFN近邻感知模块(NPM) patch嵌…

【C++】虚拟继承 组合

目录 一、虚拟继承 &#x1f31f;【非虚拟内存分布】 &#x1f31f;【虚拟继承内存分布】 &#x1f31f;【虚拟继承读取】 &#x1f31f;【练习检验】 &#x1f31f;【继承的总结和反思】 二、组合 &#x1f31f;【继承和组合】 &#x1f31f;【前言回顾】 上一篇文章我们…

MATLAB和ROS联合仿真参考资料

参考文章&#xff1a; MATLAB和ROS联合仿真篇&#xff08;从MATLAB获取ROS信息&#xff09;链接

每日一题|djwcb【算法赛】|字符串快速幂

每日一题|djwcb【算法赛】 djwcb 心有猛虎&#xff0c;细嗅蔷薇。你好朋友&#xff0c;这里是锅巴的C\C学习笔记&#xff0c;常言道&#xff0c;不积跬步无以至千里&#xff0c;希望有朝一日我们积累的滴水可以击穿顽石。 djwcb 注意&#xff1a; 快速幂字符串&#xff0c;看…

手写springboot启动器, 学习SpringBoot的最佳实践

自己手写的SpringBoot启动器, 是一个学习了解SpringBoot启动逻辑和了解springboot原理的不错的实践Demo. 废话不多说,直接上代码: 项目结构 maven多项目结构, myspringboot 自己手写的SpringBoot启动器 service-demo 用来测试SpringBoot启动器的示例项目 项目pom依赖 1.…

python、execl数据分析(数据描述)

一 python 1.各函数 1.1python库的安装与导入 #pip install os#pip install matplotlib#pip install seaborn#pip install scikit-learn#pip install scipy#修 改 工 作 目 录import osos.getcwd () # 查看当前工作环境os.chdir( F :\my course\database ) # 修改工作环境o…

fifo ip核 ————读写时钟同步

1.原理 timescale 1ns/1ns module tb_fifo();reg sys_clk ; reg sys_rst_n ; reg [7:0] pi_data ; reg rd_req ; reg wr_req ; reg [2:0] cnt;wire empty ; wire full ; wire [7:0] po_data ; wire [7:0] usedw ;initial begins…

力扣HOT100 - 283. 移动零

解题思路&#xff1a; 双指针 指针 i 用于寻找不为零的位置 指针 j 用于寻找为零的位置 不为零时&#xff0c;自己与自己交换&#xff0c;i 和 j 同时向下一个位置移动 为零时&#xff0c;nums[ i ]与nums[ j ]交换&#xff0c;使零向后移动 class Solution {public void…

总结虚函数表机制——c++多态底层原理

前言&#xff1a; 前几天学了多态。 然后过去几天一直在测试多态的底层与机制。今天将多态的机制以及它的本质分享给受多态性质困扰的友友们。 本节内容只涉及多态的原理&#xff0c; 也就是那张虚表的规则&#xff0c;有点偏向底层。 本节不谈语法&#xff01;不谈语法&#x…

发布文章积分自动增加

controller ApiOperation(value "添加文章")PostMapping("/addwengzhang")public String addwengzhang(RequestBody WengDto wengDto) {if (wengDto.getContent() null || wengDto.getTitle() null) {return "参数不可为空";}User user user…

【MySQL】InnoDB引擎

逻辑结构 InnoDB存储引擎逻辑结构如图所示&#xff1a; Tablespace&#xff1a;表空间&#xff0c;一个数据库可以对应多个表空间。数据库中的每张表都有一个表空间&#xff0c;用来存放表记录、索引等数据。 Segment&#xff1a;段&#xff0c;表空间中有多个段&#xff0c…