python协程的实现

Python协程的底层实现 生成器 协程的核心就是上下文切换,在Python中最简单的实现是用生成器 生成器有个方法 send() 可以从调用者向生成器函数发送数据,这样就可以在生成器中 yield future 表示要等待 future 的结果,然后把上下文切换到调用者,等 future 结果准备好后调用者再 send(future.result()) 给生成器发送结果,并把上下文切换到生成器函数 def gener... 阅读详情

python协程

1、协程,又称微线程,纤程。英文名Coroutine,协程并非python专属的概念,而是一个计算机概念,不同编程语言有不同的实现。
简单协程的实现

import time

def work1():
    while True:
        print("----work1---")
        yield 1
        time.sleep(0.5)

def work2():
    while True:
        print("----work2---")
        yield 2
        time.sleep(0.5)

def main():
    w1 = work1() 
    w2 = work2() 
    while True: 
        next(w1) 
        next(w2) 

if __name__ == "__main__": 
    main() 

  • yield 有让步之意,因为它交出了程序的控制权,但这个协程并没有结束,下一次执行时,将恢复到之前让出程序控制权的地方,也就是yield语句执行的地方继续执行。在上面的代码里,我创建了两个生成器(姑且认为,函数里有yiled就算生成器),也就是创建了两个协程,并且让这两个协程交替执行

想象一下,work1函数中,yield 语句执行的地方不是紧跟着一个整数,而是一个IO操作,那么这就会大大提高程序的并发。IO操作是阻塞的,耗时的,但协程可以在遇到IO操作的时候将程序的控制权让出,这个时候别的协程获得程序控制权继续执行。

一般的函数具备这样的功能么?正常我们在函数中,把程序控制权交出去,其本质不就是函数运行结束么?(使用return),无论如何也不会在中间某个位置交出控制权,过一段时间又回到这个位置继续执行,而协程就可以。

上面的代码,始终是在同一个线程内执行,这是很多人都会忽视的一个关键事实。多个协程在一个线程内协作,在协程间的切换不涉及到任何系统调用,也不会产生阻塞。

为了更好使用协程来完成多任务,python中的greenlet模块对其封装,从而使得切换任务变的更加简单

from greenlet import greenlet
import time  

def test1():  
    while True:  
        print("---A--")  
        gr2.switch()  
        time.sleep(0.5)  

def test2():  
    while True:  
        print("---B--")  
        gr1.switch()  
        time.sleep(0.5)  

gr1 = greenlet(test1)  
gr2 = greenlet(test2)  

#切换到gr1中运行  
gr1.switch() #通过调用gr1的switch方法,我们启动了gr1协程。因为gr1内部有一个while True循环,并且会不断地切换到gr2,而gr2也会不断地切换回gr1,所以这两个协程会交替执行,从而不断地在控制台打印出"---A--"和"---B--"。



  • 1、 协程与进程、线程的不同
    • 进程、线程 创建完之后,到底是哪个进程、线程执行 不确定,这要让操作系统来进行计算(调度算法,例如优先级调度)
    • 协程是可以人为来控制的
  • 2、greenlet库提供的协程是完全由用户控制的,这意味着我们需要显式地调用switch方法来在协程之间进行切换。这与Python内置的async/await语法(用于异步编程)有所不同,后者提供了更高级别的协程控制,并且可以自动处理协程之间的切换。
import gevent


def f1(n):
    for i in range(n):
        print("-----f1-----", i)


def f2(n):
    for i in range(n):
        print("-----f2-----", i)


def f3(n):
    for i in range(n):
        print("-----f3-----", i)


g1 = gevent.spawn(f1, 5)
g2 = gevent.spawn(f2, 5)
g3 = gevent.spawn(f3, 5)
g1.join()  # join会等待g1标识的那个任务执行完毕之后 对其进行清理工作,其实这就是一个 耗时操作
g2.join()# 等待g2标识的协程(即f2函数的执行)完成
g3.join()# 等待g3标识的协程(即f3函数的执行)完成

在这里插入图片描述

  • 1、可以看到,3个greenlet是依次运行而不是交替运行

  • 2、使用gevent来实现多任务的时候,有一个很特殊的地方它可以自行切换协程指定的任务,而且切换的前提是:当一个任务用到耗时操作(例如延时),它就会把这个时间拿出来去做另外的任务,这样做最终实现了多任务 而且自动切换,如下

import gevent


def f1(n):
    for i in range(n):
        print("-----f1-----", i)
        gevent.sleep(1)


def f2(n):
    for i in range(n):
        print("-----f2-----", i)
        gevent.sleep(1)


def f3(n):
    for i in range(n):
        print("-----f3-----", i)
        gevent.sleep(1)


g1 = gevent.spawn(f1, 5)
g2 = gevent.spawn(f2, 5)
g3 = gevent.spawn(f3, 5)
g1.join()  # join会等待g1标识的那个任务执行完毕之后 对其进行清理工作,其实这就是一个 耗时操作
g2.join()
g3.join()

# 使用gevent来实现多任务的时候,有一个很特殊的地方
# 它可以自行切换协程指定的任务,而且切换的前提是:当一个任务用到耗时操作(例如延时),它就会把这个时间拿出来去做另外的任务
# 这样做最终实现了多任务 而且自动切换

在这里插入图片描述
3、并发下载视频
1、可以将url换为自己需要下载视频、音乐、图片等网址,重新执行即可完成下载

from gevent import monkey
import gevent
import urllib.request
import ssl

monkey.patch_all()

ssl._create_default_https_context = ssl._create_unverified_context


def my_downLoad(file_name, url):
    print('GET: %s' % url)
    resp = urllib.request.urlopen(url)
    data = resp.read()

    with open(file_name, "wb") as f:
        f.write(data)

    print('%d bytes received from %s.' % (len(data), url))


gevent.joinall([
    gevent.spawn(my_downLoad, "1.mp4", '视频URL地址'),
    gevent.spawn(my_downLoad, "2.mp4", '视频URL地址2')
])

Python协程与Go协程的实现差异分析 Python协程和Go协程的实现方式确实有很大差异,这主要是由于两种语言的设计理念、历史背景和目标用途不同。 阅读详情

相关推荐

DEXPI与Proteus XML:解锁过程工业P&ID数据互操作性的技术核心

本文深入探讨了DEXPI与Proteus XML在过程工业P&ID数据互操作性中的核心技术。通过解析DEXPI标准的开源特性和Proteus XML的架构设计,揭示了其在跨平台数据交换中的关键作用,并结合CADMATIC和西门子COMOS的实战案例,展示了如何实现高效的数据集成与转换。

weixin_29195615的博客 383

Python协程的四种实现方式

今天继续给大家介绍Python关知识,本文主要内容是Python协程的四种实现方式。 一、yield关键字实现方式 二、greenlet实现方式 三、asyncio实现方式 四、async和await关键字实现方式

永远是少年 4695

Ansys-结构动力学分析-圆柱斜齿轮模态分析学习心得

模态分析的步骤基本一直,不同点在于选择什么单元类型,模型,节点约束等 圆柱斜齿轮模态分析的难点在于圆柱斜齿轮的模型建立,和所要约束的节点的选择。 用命令流方法建立齿轮模型效率较高,当然,在ansys里建立复杂的模型实在不敢恭维,对于自下而上建模,需要知道每个关键点的坐标位置。下图是创建圆柱斜齿轮模型的命令流方式。 模型不同使用的数据也就不同了。 对于施加约束的问题这就必须要熟悉select e...

weixin_45385183的博客 1831

python 协程 (概念+示例代码)

1. 迭代器 1.1 迭代器应用:自定义列表 1.2 迭代器应用:斐波那契数列 2. 生成器 2.1 生成器案例:斐波那契数列 2.2 生成器注意事项 3. 协程 3.1 yield 简单实现协程 3.2 greenlet实现协程 3.3 gevent实现协程

ChaoChao66666的博客 1346

Linux下自动化解析q7签名文件的有效期与时间戳

本文详细介绍了在Linux环境下自动化解析q7签名文件有效期与时间戳的方法。通过编写高效脚本,开发者可以批量提取签名时间信息,验证签名有效性,并集成到CI/CD流程中。文章提供了完整的脚本实现,包括错误处理、批量处理功能,并解决了常见环境问题,特别适用于国产操作系统如UOS的开发场景。

weixin_30872499的博客 520

NACA0012的O型网格求解

本篇文章采用偏微分方程数值解法生成NACA0012翼型O型网格,并采用速度势方程求解绕NACA0012翼型迎角为0度时的低速不可压无粘流场。 文章目录一、求解网格1.翼型2.远场3.网格4.迭代5.求解二、求解流场1.偏微分方程2.迭代求解流场三、求解参数1.偏微分方程2.迭代求解四、导出数据 一、求解网格 1.翼型 本次求解网格和流场等采用的是NACA0012(修形)对称翼型,在NACA四位翼型中,第一位数字代表的是弯度,第二位数字代表的是弯度位置,后两位数字代表的是厚度,由于本次翼型的前两位数字都为0,

m0_50746433的博客 6677

python协程实现

在协程中,只要和IO任务类似的、耗费时间的任务都需要使用yield from 来进行中断,达到异步功能。通过 async & await 来将一个函数分成多个段,而这些段都是协程里面调度的单位,粒度比进程、线程都要小。uvloop是asyncio事件循环的替代方案,在效率上uvloop事件循环 > python默认的asyncio事件循环。协程,也可以被称为微线程,是一种用户态内的上下文切换技术。进程和线程是内核级别的程序,而协程是函数级别的程序,是可以通过人为调用函数来实现的,核心机制就是。

优快云1csdn1的博客 387

ArcGIS新手必看:用Landsat 8数据计算植被覆盖度的完整流程(附DEM裁剪技巧)

本文为ArcGIS新手提供了使用Landsat 8数据计算植被覆盖度的完整流程指南。详细讲解了从数据预处理、NDVI计算到基于像元二分模型反演植被覆盖度的核心步骤,并重点分享了利用DEM进行精确裁剪的实用技巧,帮助用户高效完成地表信息提取与分析。

weixin_29279047的博客 239

Python多进程、多线程、协程典型示例解析

作用:创建多个独立运行的进程(每个进程有独立内存空间)适用场景:数学计算、图像处理等CPU密集型任务核心原理:绕过Python的GIL锁,真正利用多核CPU作用:创建多个线程(共享同一进程内存)适用场景:文件读写、网络请求等I/O等待型任务核心特点:受GIL限制,同一时刻只能有一个线程执行Python字节码作用:单线程内通过任务切换实现高并发适用场景:Web服务器、高频I/O操作(如爬虫)核心机制:事件循环(Event Loop)驱动协程切换特性threadingasyncio。

漫谈网络 3587

手把手教你用Docker快速部署开源MES系统(附避坑指南)

本文提供了一份详细的实战指南,手把手教你使用Docker容器化技术快速部署开源MES系统。内容涵盖从环境准备、项目选型、数据库配置到应用服务器优化、前端部署及生产环境监控的全流程,并附有避坑指南,旨在帮助中小制造企业IT人员和开发者低成本、高效率地构建智能制造解决方案。

f0g1h2的博客 1059

WOFOST作物模型(1):PCSE环境配置

get_summary_output() 方法通常用于在 PCSE 模拟过程结束后,获取模拟结果的摘要信息,例如模拟期间的总产量、总水分需求等。它可以提供对模拟结果的快速总结,方便用户进行后续的分析和处理。用.get_output来获取过程参数,并将这些参数转为dataframe显示。用run_till_terminate()代表终止。安装好之后,打开jupyter notebook。也可以指定运行时间,并获取最后一天的参数。首先还是打开之前建好的gee虚拟环境。

所有专家都曾始于新手 681

python 协程实现

协程,又称微线程,纤程。英文名Coroutine。协程不是计算机提供的,是人为创造的上下文切换技术,也可以被称为微线程。简而言之 其实就是在一个线程中实现代码块相互切换执行。

cliffordl的专栏 1596

(5)ModalAI VOXL2

Ardupilot官网关于《Non-GPS navigation》的翻译 —《(5) ModalAI VOXL2》。

无人机开发(开源Ardupilot) 1万+

python协程的实现_Python 实现协程

协程的概念协程,又称微线程,纤程。英文名Coroutine。一句话说明什么是线程:协程是一种用户态的轻量级线程。(其实并没有说明白~)我觉得单说协程,比较抽象,如果对线程有一定了解的话,应该就比较好理解了。那么这么来理解协程比较容易:线程是系统级别的,它们是由操作系统调度;协程是程序级别的,由程序员根据需要自己调度。我们把一个线程中的一个个函数叫做子程序,那么子程序在执行过程中可以中断去执行别的子...

weixin_39767513的博客 191

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

python实现协程的三种方式

1.使用yield 来实现协程 import asyncio import time async def job(t): # async 形式的功能 print('Start job ', t) await asyncio.sleep(t) # 等待 "t" 秒, 期间切换其他任务 print('Job ', t...

u011089760的博客 6374

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

python协程的实现_Python之协程的实现

1、Python里面一般用gevent实现协程协程,而协程就是在等待的时候切换去做别的操作,相当于将一个线程分块,充分利用资源(1)低级版协程的实现import geventdef test1():print(1,2)gevent.sleep(0)#执行到这里的时候切换去函数test2print(3,4)def test2():print(5,6)gevent.sleep(0)print(7,8)...

weixin_39868592的博客 166

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Python使用gevent实现协程

Python使用gevent实现协程 Python中多任务的实现可以使用进程和线程,也可以使用协程。 一、协程介绍 协程,又称微线程。英文名Coroutine。协程是Python语言中所特有的,在其他语言中没有。 协程是python中另外一种实现多任务的方式,比线程更小、占用更小执行单元(理解为需要的资源)。 在一个线程中的某个函数,可以在任何地方保存当前函数的一些临时变量等信息,然后切...

weixin_43790276的博客 2787

python实现协程

协程(Coroutine)是一种轻量级的并发编程技术,它允许程序在某个点上暂停执行,并在稍后恢复执行,而不是像线程那样在不同的执行上下文中切换。在Python中,可以使用 threading 模块创建和管理线程,由于全局解释器锁(GIL)的存在,Python中的线程并不能充分利用多核CPU,适合用于IO密集型任务。在Python中,可以使用 asyncio 模块来实现协程,它提供了事件循环(event loop)来调度协程的执行,适合用于IO密集型任务和高并发的网络应用。不会受到 GIL 的影响。

liulanba的博客 610

协程的理解以及python实现协程

协程 协程 协程是一种比线程更加轻量级的存在,正如一个进程可以拥有多个线程一样,一个线程可以拥有多个协程。协程不是被操作系统内核管理,而是完全由程序所控制。线程和进程的操作是由程序触发系统接口,最后的执行者是系统,协程的操作是程序员。 意义:对于多线程的应用,CPU通过切片的方式来切换协程之间的执行,线程之间的切换需要耗时(保存状态,下次继续)。协程则只使用一个线程(单线程),在一个线程...

一只菜鸟的博客 358

python yield 协程_用yield实现python协程

刚刚介绍了pythonyield关键字,趁热打铁,现在来了解一下yield实现协程。引用官方的说法:与线程相比,协程更轻量。一个python线程大概占用8M内存,而一个协程只占用1KB不到内存。协程更适用于IO密集型的应用。当然在讲协程的实现之前,有必要先来看一下send方法。send方法yield表达式有一个返回值,send方法的作用就是控制这个返回值,send的参数就是yield表达式的返回值...

weixin_36311421的博客 828

python协程的实现_python协程实现

参考:协程的概念协程,又称微线程,纤程。英文名Coroutine。协程是程序级别的,由程序自己决定如何调度。协程的概念:在子程序执行过程中可以中断去执行别的子程序,而别的子程序也可以中断回来继续执行之前的子程序,这个过程就称为协程。类似与yield操作。协程的优点:无需线程切换上下文,避免了无意义的调度。可以提高程序性能。无需原子操作锁定及同步的开销方便切换控制流,简化编程模型高并发+高扩展性+低...

weixin_42507981的博客 356

python3异步协程爬虫_Python实现基于协程的异步爬虫

Python实现基于协程的异步爬虫一、课程介绍1. 课程来源本课程核心部分来自《500 lines or less》项目,作者是来自 MongoDB 的工程师 A. Jesse Jiryu Davis 与 Python 之父 Guido van Rossum。项目代码使用 MIT 协议,项目文档使用http://creativecommons.org/licenses/by/3.0/legalc...

weixin_28803105的博客 279

Python 协程实现异步

今日主题:前面分享过Python 通过使用回调函数如何实现异步的处理,今天我们将通过一个简单的示例来讲解一下协程是如何实现异步的处理的。 协程的概念 协程,又称微线程,是一种用户态的轻量级线程。协程能保留上一次调用时的状态,每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置,当程序中存在大量不需要CPU的操作时(IO),适用于协程。 协程的优势 协程有极高的执行效率,因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销。 不需要..

Python+大数据+数据分析+自动化+Vue组件开发 389
上一篇: python多线程和多进程的实现
下一篇: Linux环境如何安装python
十二月将至
博客等级 码龄8年 380粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值