协程,又称微线程,纤程。英文名Coroutine。
协程是啥
协程是python个中另外一种实现多任务的方式,只不过比线程更小占用更小执行单元(理解为需要的资源)。 为啥说它是一个执行单元,因为它自带CPU上下文。这样只要在合适的时机, 我们可以把一个协程 切换到另一个协程。 只要这个过程中保存或恢复 CPU上下文那么程序还是可以运行的。
通俗的理解:在一个线程中的某个函数,可以在任何地方保存当前函数的一些临时变量等信息,然后切换到另外一个函数中执行,注意不是通过调用函数的方式做到的,并且切换的次数以及什么时候再切换到原来的函数都由开发者自己确定
协程和线程差异
在实现多任务时, 线程切换从系统层面远不止保存和恢复 CPU上下文这么简单。 操作系统为了程序运行的高效性每个线程都有自己缓存Cache等等数据,操作系统还会帮你做这些数据的恢复操作。 所以线程的切换非常耗性能。但是协程的切换只是单纯的操作CPU的上下文,所以一秒钟切换个上百万次系统都抗的住。
协程是一种 "假" 的线程, 之所以这样说,主要是因为它并非真的开启一个线程,而是通过复杂的逻辑算法实现一个
伪线程的东西。与真线程相比,协程消耗的资源极少.在Python开发中,进行耗时操作过程中最好建议优先考虑这样的
顺序 : 协程 > 线程 > 进程。
因为使用协程中一般不考虑使用yield, greenlet, 所以本章中直接使用gevent。
提示 : gevent 封装 greenlet, 而 greenlet 封装了 yield, yield 是使用 协程的最小单位。
代码如下:
#! /usr/bin/python3.7 import urllib.request import gevent def downloader(file_name, file_url): req = urllib.request.urlopen(file_url) file_content = req.read() with open(file_name, "wb") as f: f.write(file_content) def main(): video_url1 = "https://vd3.bdstatic.com/mda-jegppeankjyr5ta3/sc/mda-jegppeankjyr5ta3.mp4?auth_key=1558950819-0-0" \ "-3c6631b3f2948e9b2d2aba6f890d4818&bcevod_channel=searchbox_feed&pd=bjh&abtest=all " video_url2 = "https://vd2.bdstatic.com/mda-jcag47e758miucrp/sc/mda-jcag47e758miucrp.mp4?auth_key=1558951118-0-0-" \ "1b208f33ef8dbf745999789beef8d16e&bcevod_channel=searchbox_feed&pd=bjh&abtest=all" gevent.joinall([ # 图片下载 # gevent.spawn(downloader, "1.png", "https://avatar.52pojie.cn/data/avatar/000/32/94/89_avatar_middle.jpg"), # gevent.spawn(downloader, "2.png", "http://file06.16sucai.com/2018/0530/82d75b22ed343e80e58d95ac1b60c753.jpg") # 视频下载 gevent.spawn(downloader, "1.mp4", video_url1), gevent.spawn(downloader, "2.mp4", video_url2) ]) if __name__ == "__main__": main()
本人第一次写博客, 仅用于总结和学习,如有错误, 大牛轻喷哈。