Python、Rust中的协程
协程
协程在不同的堆栈上同时运行,但每次只有一个协程运行,而其调用者则等待:
- F启动G,但G并不会立即运行,F必须显式的恢复G,然后 G 开始运行。
- 在任何时候,G 都可能转身并让步返回到 F。这会暂停 G 并继续 F 的恢复操作。
- F再次调用resume,这会暂停F并继续G的yield。它们不断地来回移动,直到 G 的
return
,这会清理 G 并从最近的恢复中继续 F,并向 F 发出一些信号,表明 G 已完成并且 F 不应再尝试恢复 G。 - 在这种模式中,一次只有一个协程运行,而其调用者则在不同的堆栈上等待。
归根结底,协程的产生是为了非常快速地切换每个线程上当前运行的任务,这样所有的任务都有机会运行。
从阻塞(blocking
)说起
Python
和Rust
的async/await
是通过协作型调度(cooperative scheduling
)来完成的。
Golang
的Goruntine
则是抢占式调度(Preemptive multitasking
)。
运行时(Runtime
)
在写异步Rust和Python的时候,Block
意味着阻止运行时切换当前任务
。
运行时(Runtime
),也称为执行时或运行阶段,是指计算机程序在实际运行时执行的阶段,与编译时相对应。在程序的运行时阶段,计算机程序被加载到内存中,操作系统控制程序的执行,处理输入和输出,以及管理计算机的资源。
在常规多线程编程中,每个线程都有自己的运行时(Runtime
)。由于GIL
,进程级别以下的python只有一个运行时,无论启动多少个线程,他们都共享相同的Runtime
。
Notice:
CPython 是 Python 的标准实现,它是用C语言编写的,是最常用的 Python 解释器。CPython解释器在运行Python程序时,将Python源代码翻译成字节码,并在Python虚拟机(Python Virtual Machine,简称PVM)上执行。因此,Python程序在CPython下运行时,实际上是在Python虚拟机中运行的,这个虚拟机叫做Python运行时。
await
为了防止上述情况,我们需要在异步编程的时候,注意一点: 避免长时间不使用await
coroutine in Python
Python的协程通常是通过事件循环(Event Loop
)来调度的,事件循环是一个轮询机制,它负责管理协程的执行、挂起、恢复和调度,通过
await
关键字来挂起和恢复, 通过异步生成器来保存函数的状态。
事件循环的原理如下:
- 单线程执行: 事件循环运行在一个单线程环境中,这个线程负责执行所有任务,包括异步任务。
- 任务队列: 事件循环维护一个任务队列,其中包含等待执行的任务,包括异步任务和事件处理程序。
- 事件驱动: 事件循环是事件驱动的,它会监听各种事件,如I/O事件、定时器事件、信号等。
- 挂起和恢复: 当任务需要等待某些条件满足时,它会被挂起,释放CPU资源,允许其他任务继续执行。
源码如下:
def _run_once(self):"""Run one full iteration of the event loop.This calls all currently ready callbacks, polls for I/O,schedules the resulting callbacks, and finally schedules'call_later' callbacks."""sched_count = len(self._scheduled)if (sched_count > _MIN_SCHEDULED_TIMER_HANDLES andself._timer_cancelled_count / sched_count >_MIN_CANCELLED_TIMER_HANDLES_FRACTION):# Remove delayed calls that were cancelled if their number# is too highnew_scheduled = []for handle in self._scheduled:if handle._cancelled:handle._scheduled = Falseelse:new_scheduled.append(handle)heapq.heapify(new_scheduled)self._scheduled = new_scheduledself._timer_cancelled_count = 0else:# Remove delayed calls that were cancelled from head of queue.while self._scheduled and self._scheduled[0]._cancelled:self._timer_cancelled_count -= 1handle = heapq.heappop(self._scheduled)handle._scheduled = Falsetimeout = Noneif self._ready or self._stopping:timeout = 0elif self._scheduled:# Compute the desired timeout.when = self._scheduled[0]._whentimeout = min(max(0, when - self.time()), MAXIMUM_SELECT_TIMEOUT)event_list = self._selector.select(timeout)self._process_events(event_list)# Needed to break cycles when an exception occurs.event_list = None# Handle 'later' callbacks that are ready.end_time = self.time() + self._clock_resolutionwhile self._scheduled:handle = self._scheduled[0]if handle._when >= end_time:breakhandle = heapq.heappop(self._scheduled)handle._scheduled = Falseself._ready.append(handle)# This is the only place where callbacks are actually *called*.# All other places just add them to ready.# Note: We run all currently scheduled callbacks, but not any# callbacks scheduled by callbacks run this time around --# they will be run the next time (after another I/O poll).# Use an idiom that is thread-safe without using locks.ntodo = len(self._ready)for i in range(ntodo):handle = self._ready.popleft()if handle._cancelled:continueif self._debug:try:self._current_handle = handlet0 = self.time()handle._run()dt = self.time() - t0if dt >= self.slow_callback_duration:logger.warning('Executing %s took %.3f seconds',_format_handle(handle), dt)finally:self._current_handle = Noneelse:handle._run()handle = None # Needed to break cycles when an exception occurs.
- 通过
_selector.select(timeout)
返回一个任务状态列表 - 使用
_process_events
处理就绪的I/O任务 - 多次运行
_run_once
,直到所有任务处理完毕,事件循环中没有待执行的任务。
相关文章:
Python、Rust中的协程
协程 协程在不同的堆栈上同时运行,但每次只有一个协程运行,而其调用者则等待: F启动G,但G并不会立即运行,F必须显式的恢复G,然后 G 开始运行。在任何时候,G 都可能转身并让步返回到 F。这会暂停 G 并继续…...

Vuepress样式修改内容宽度
1、相关文件 一般所在目录node_modules\vuepress\theme-default\styles\wrapper.styl 2、调整宽度,截图中是已经调整好的,在我电脑上显示刚刚好。...

Vue2电商前台项目——项目的初始化及搭建
Vue2电商前台项目——项目的初始化及搭建 Vue基础知识点击此处——Vue.js 文章目录 Vue2电商前台项目——项目的初始化及搭建一、项目初始化1、脚手架目录介绍2、项目的其他配置 二、项目的路由分析及搭建1、项目的路由分析2、开发项目的步骤3、非路由组件的搭建4、路由组件的搭…...

递归算法学习——N皇后问题,单词搜索
目录 编辑 一,N皇后问题 1.题意 2.解释 3.题目接口 4.解题思路及代码 二,单词搜索 1.题意 2.解释 3.题目接口 4.思路及代码 一,N皇后问题 1.题意 按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上…...
【SpringBoot】mockito+junit 单元测试
1.POM 引入以下依赖 <dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency><dependency><groupId>org.springframework.b…...

webserver 同步 I/O 模拟 Proactor 模式的工作流程
服务器基本框架、I/O 模型、事件处理模式 一、服务器编程基本框架 虽然服务器程序种类繁多,但其基本框架都一样,不同之处在于逻辑处理。 二、五种 I/O 模型 阻塞/非阻塞、同步/异步(网络IO)_呵呵哒( ̄▽ ̄)&…...
mysql8-基于docker搭建主从同步
一、环境信息 系统版本:CentOS Linux release 7.9.2009 (Core) cat /etc/centos-release Docker版本:Docker version 20.10.6, build 370c289 docker --version Docker-compose版本:Docker Compose version v2.10.2 docker-compose --versio…...

智能水表远程控制系统:引领节水新时代
随着科技的不断发展,物联网技术逐渐融入到我们的日常生活中。其中,智能水表远程控制系统成为一项重要创新,对于提高水资源利用率、实现绿色节水具有重要意义。下面小编就来为大家介绍下智能水表远程控制系统吧! 一、智能水表远程控制系统定义…...

【FusionInsight 迁移】HBase从C50迁移到6.5.1(03)6.5.1上准备Loader
【FusionInsight 迁移】HBase从C50迁移到6.5.1(03)6.5.1上准备Loader HBase从C50迁移到6.5.1(03)6.5.1上准备Loader登录新集群FusionInsight 6.5.1的Manager准备Loader服务准备Loader Role准备Loader User HBase从C50迁移到6.5.1&…...
redis多线程操作
今天更新一个redis多线程操作, 可直接搬运 import redis, os, threading, queue import pandas as pd# 创建一个任务队列 task_queue queue.Queue()def read_excel(folder_path):total_list []for filepath, dirnames, filenames in os.walk(folder_path):for fi…...
OpenCV(十七):拉普拉斯图像金字塔
1.拉普拉斯图像金字塔原理 拉普拉斯图像金字塔是一种多尺度图像表示方法,通过对高斯金字塔进行差分运算得到。它能够提供图像在不同尺度上的细节信息,常用于图像处理任务如图像增强、边缘检测等。 下面是拉普拉斯图像金字塔的原理和步骤: 构…...

OpenCL编程指南-10.2使用C++包装器API的矢量相加示例
选择OpenCL平台并创建一个上下文 建立OpenCL的第一步是选择一个平台。第2章介绍过,OpenCL使用了ICD模型,其中可以有多个OpenCL实现在一个系统上并存。类似于HelloWorld示例,这个矢量相加程序展示了选择OpenCL平台的一种最简单的方法…...

mysql数据库,字符串使用双引号““导致报错,使用单引号‘‘不报错,Unknown column ‘user-test‘ in ‘where clause‘
文章目录 一、完整报错二、报错数据三、报错原因四、解决方式1、更改执行sql2、更改sql数据校验模式(改为默认校验) 一、完整报错 > 1054 - Unknown column user-test in where clause二、报错数据 SELECT * FROM config_info WHERE config_info.da…...

[华为云云服务器评测] 华为云耀云服务器 Java、node环境配置
系列文章目录 第一章 [linux实战] 华为云耀云服务器L实例 Java、node环境配置 文章目录 系列文章目录前言一、任务拆解二、修改密码三、配置安全规则四、远程登录并更新apt五、安装、配置JDK环境5.1、安装openjdk,选择8版本5.2、检查jdk配置 六、安装、配置git6.1、安装git6.2…...

中企绕道突破封锁,防不胜防 | 百能云芯
韩国的财经媒体Business Korea最新报道指出,尽管美方在《通胀削减法案》(IRA)的补贴中排除了中国,但中国企业正通过多种方式积极应对美国在半导体和电动汽车电池领域的封锁,这包括建立合资企业、设立生产基地以及开展技…...

动手实践:从栈帧看字节码是如何在 JVM 中进行流转的
Java全能学习面试指南:https://www.javaxiaobear.cn/ 前面我们提到,类的初始化发生在类加载阶段,那对象都有哪些创建方式呢?除了我们常用的 new,还有下面这些方式: 使用 Class 的 newInstance 方法。使用…...

PEX装机
目录 一、PXE是什么? 二、PXE的组件: vsftpd/httpd/nfs tftp dhcp 三、配置vsftpd 四、配置tftp 1.安装tftp-server 2.启动tftp 五、准备pxelinx.0文件、引导文件、内核文件 1.准备pxelinux.0文件 2.准备引导文件、内核文件 六、配置dhcp …...

异地远程访问内网BUG管理系统【Cpolar内网穿透】
文章目录 前言1. 本地安装配置BUG管理系统2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射本地服务3. 测试公网远程访问4. 配置固定二级子域名4.1 保留一个二级子域名5.1 配置二级子域名6. 使用固定二级子域名远程 前言 BUG管理软件,作为软件测试工程师的必备工具之一。在…...

论文笔记:一分类及其在大数据中的潜在应用综述
0 概述 论文:A literature review on one‑class classification and its potential applications in big data 发表:Journal of Big Data 在严重不平衡的数据集中,使用传统的二分类或多分类通常会导致对具有大量实例的类的偏见。在这种情况…...

下单时如何保证数据一致性?
原创 哪吒 哪吒编程 2023-09-07 08:03 发表于辽宁 收录于合集#Redis11个 (给哪吒编程加星标,提高Java技能) 大家好,我是哪吒。 在前几篇文章中,提到了Redis实现排行榜、Redis数据缓存策略,让我们对Redis…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...

云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...

人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...