热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Python协程简介

Python协程简介什么是协程代码实现总结当我们要完成一个简单的任务的时候,我们通常就是按照事件的先后顺序按照过程编程,同头到尾程序逐行执行࿰

Python 协程简介

  • 什么是协程
  • 代码实现
  • 总结



当我们要完成一个简单的任务的时候,我们通常就是按照事件的先后顺序按照过程编程,同头到尾程序逐行执行,当我们需要实现的功能越复杂对性能要求越高时我们开始慢慢引入了多线程、多进程、协程等概念,多线程和多进程这个比较好理解,但是协程可能平时就见的不多了,本文对Python 协程到底是什么做出简介。以下全是个人理解如有不妥请多多指正。
什么是协程

根据维基百科给出的定义,“协程 是为非抢占式多任务产生子程序的计算机程序组件,协程允许不同入口点在不同位置暂停或开始执行程序”。听上去感觉很难懂,这里举上一个小小的例子,多线程和多进程都是可以理解为有多个CPU在确实的运行相应的程序,程序并没有发生中断,而协程是运行发生中断的,何时发生中断是由用户决定,产生中断后当前的函数停止工作转而去执行另外一个函数,这个对于嵌入式的中断有点这种意思,单片机当中现在正在运行main函数,这个时候外部中断触发了,main暂时停止转而去执行中断函数,这个时候可能会出现一个想法这不在函数里面调用另外一个函数也是实现的相同功能吗,注意这只是说协程表现出来的一种形式,协程是协调个部分代码达到资源最大利用,这才是真正的协程,在协程中要有任务的安排调整
讲个故事可能来的比较快一点,现在我们要做的一件事那就是安装Ubuntu系统,之前通过问别人我们大概知道了操作流程是先下载镜像文件,然后在进制作启动盘然后吧啦吧啦一系列操作,好现在我们就用一个单线程的人来模拟这个过程,首先我们进入一个操作也就是程序的一个函数,我们先下载镜像,先打开网站之后一顿操作过后就显示下载进度条了,注意这个动作(想象成程序的函数)还没有执行完,因为我们还没有下载完整个镜像,这个时候我们就开始等进度条,一秒过去了没下载完,我们再等等,两秒过去了还没下载完,这个时候我们就开始不耐烦了,我看进度条显示下载还剩余10分钟,我们好像可以干点别的事情,等下载完过后再来操作,我们这个时候就不再等待了下载了,转而去网站上看等会下载完成了怎么制作启动盘,这个时候我们就实现了任务的调度,从下载镜像转到了流量网页。协程就是这样发生在一个可能发生长时间阻塞的地方,我们不是让CPU做无用的等待,而是让CPU在等待的时间干点其他有用的事情,我们手动进行任务切换的过程就是协程。

代码实现

Python的协程经历了很长的发展,由于只是简介,只介绍最常用也是最简单的一种用法
我们编写一个程序模拟刚才的过程
首先采用最我们用延迟模拟这个过程的耗时,最后统计总的耗时时间

import time def download_ubuntu():time.sleep(5)# 查阅相关操作的教程
def look_up_how_to_operate():time.sleep(3)def install_ubuntu():download_ubuntu()look_up_how_to_operate()def main():start = time.time()install_ubuntu()end = time.time()print ('Cost {} seconds'.format(end - start))if __name__ == "__main__":main()

运行这段代码,我们得到下面的运行时间,无疑就是各个操作时间的累加

Cost 8.004846334457397 seconds

下面我们开始优化过程

import asyncio
import time # 用async表示这个是一个异步的函数表示这个函数是可发生中断的
async def download_ubuntu():# await后面需要解释一个可等待的对象,可以等待对象可以理解为async声明的函数或者具有__await__ 属性的对象,这个时候保存函数的状态跳出函数转而去执行其他的操作await asyncio.sleep(5)async def look_up_how_to_operate():await asyncio.sleep(3)def install_ubuntu():# 创建一个事件循环进而实现任务的调度loop = asyncio.get_event_loop()tasks = [download_ubuntu(),look_up_how_to_operate()]loop.run_until_complete(asyncio.wait(tasks))loop.close()def main():start = time.time()install_ubuntu()end = time.time()print ('Cost {} seconds'.format(end - start))if __name__ == "__main__":main()

通过计时我们看到时间明显就缩短了,将其中的3s就优化出来了,是不是很神奇。

Cost 5.0030436515808105 seconds

应该是在Python 3.5之后提出了这种新的async/await的操作,在以前的操作中协程还是很麻烦的,但是这种提供了很方便的操作,这个例子或许不是特别的合适下一篇博客会在ROS的实践中继续讲解协程。在本文末尾会对代码做出简要的讲解。

总结

总结起来协程就是实现用户自己编写代码级别的任务的调度。发生在我们需要调用其它模块的函数,这个函数是请求其他模块的一个函数,我们对本线程的任务做出相应的调整。
将一个函数声明为async就表示这个函数是一个可以被中断的异步函数,在产生中断过后去执行其他的函数。await关键字表示等待这个步骤完成,这个关键字后面跟的必须是一个可以等待的对象不然就会报错。


推荐阅读
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • 本文介绍了Python对Excel文件的读取方法,包括模块的安装和使用。通过安装xlrd、xlwt、xlutils、pyExcelerator等模块,可以实现对Excel文件的读取和处理。具体的读取方法包括打开excel文件、抓取所有sheet的名称、定位到指定的表单等。本文提供了两种定位表单的方式,并给出了相应的代码示例。 ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 本文介绍了在Linux下安装Perl的步骤,并提供了一个简单的Perl程序示例。同时,还展示了运行该程序的结果。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文讨论了Kotlin中扩展函数的一些惯用用法以及其合理性。作者认为在某些情况下,定义扩展函数没有意义,但官方的编码约定支持这种方式。文章还介绍了在类之外定义扩展函数的具体用法,并讨论了避免使用扩展函数的边缘情况。作者提出了对于扩展函数的合理性的质疑,并给出了自己的反驳。最后,文章强调了在编写Kotlin代码时可以自由地使用扩展函数的重要性。 ... [详细]
  • 31.项目部署
    目录1一些概念1.1项目部署1.2WSGI1.3uWSGI1.4Nginx2安装环境与迁移项目2.1项目内容2.2项目配置2.2.1DEBUG2.2.2STAT ... [详细]
  • RouterOS 5.16软路由安装图解教程
    本文介绍了如何安装RouterOS 5.16软路由系统,包括系统要求、安装步骤和登录方式。同时提供了详细的图解教程,方便读者进行操作。 ... [详细]
  • 树莓派语音控制的配置方法和步骤
    本文介绍了在树莓派上实现语音控制的配置方法和步骤。首先感谢博主Eoman的帮助,文章参考了他的内容。树莓派的配置需要通过sudo raspi-config进行,然后使用Eoman的控制方法,即安装wiringPi库并编写控制引脚的脚本。具体的安装步骤和脚本编写方法在文章中详细介绍。 ... [详细]
  • WhenIusepythontoapplythepymysqlmoduletoaddafieldtoatableinthemysqldatabase,itdo ... [详细]
author-avatar
ngzhaicai9672364
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有