协程

协程与线程差异
  在实现多任务时, 线程切换从系统层面远不止保存和恢复 CPU上下文这么简单。 操作系统为了程序运行的高效性每个线程都有自己缓存Cache等等数据,操作系统还会帮你做这些数据的恢复操作。 所以线程的切换非常耗性能。但是协程的切换只是单纯的操作CPU的上下文,所以一秒钟切换个上百万次系统都抗的住。
  
原理
  协程是python个中另外一种实现多任务的方式,只不过比线程更小占用更小执行单元(理解为需要的资源)。为什么说它是一个执行单元,因为它自带CPU上下文。这样只要在合适的时机, 我们可以把一个协程 切换到另一个协程。 只要这个过程中保存或恢复 CPU上下文那么程序还是可以运行的。

1.简单实现协程
例:

import timedef work1():while True:print('work1----------')yieldtime.sleep(0.5)def work2():while True:print('work2---')yieldtime.sleep(0.5)if __name__ == '__main__':w1 = work1()w2 = work2()while True:next(w1)next(w2)

将work函数用yield改写为生成器,并且可以保存暂停当前函数内容,下次执行时继续,使得work1和work2交替执行。

2.greenlet创建
例:

from greenlet import greenlet
import timedef 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()

开发者使用switch()方法手动切换协程,也实现了两个函数交替执行

3.gevent创建
自动调度的协程,识别耗时操作自动进行协程切换
gevent.spawn(函数名, 参数)
join:使主线程等待写执行完毕再结束
joinall(列表):让主线程等待协程执行完毕再结束

import geventdef work1():for i in range(5):print("work1 -----1")gevent.sleep(0.5)def work2():for i in range(5):print("work2 -----2")gevent.sleep(0.5)# 创建携程并指派任务
# g1 = gevent.spawn(work1)
# g2 = gevent.spawn(work2)
# 等待协程执行完成再关闭主线程
# g1.join()
# g2.join()
# 等价于
gevent.joinall([gevent.spawn(work1), gevent.spawn(work2)])

4.注意
  gevent中不识别time.sleep()等方法,它有自己的sleep()方法,如果要用time.sleep()等方法,需要打猴子补丁:

from gevent import monkey
monkey.patch_all()

查看当前执行的协程名称:gevent.getcurrent()

5.案例(并发下载器):

import urllib.request
import geventdef img_download(url, file_name):try:img_file = urllib.request.urlopen(url)with open(file_name, "wb") as file:while True:img_data = img_file.read(1024)if img_data:file.write(img_data)else:breakexcept:print("文件%s下载异常" % file_name)else:print("文件%s下载成功" % file_name)if __name__ == '__main__':img_url1 = "http://img.mp.itc.cn/upload/20170716/8e1b835f198242caa85034f6391bc27f.jpg"img_url2 = "http://pic1.wed114.cn/allimg/180227/1023303521-1.gif"img_url3 = "http://image.uczzd.cn/11867042470350090334.gif?id=0&from=export"gevent.joinall([gevent.spawn(img_download, img_url1, "1.gif"),gevent.spawn(img_download, img_url2, "2.gif"),gevent.spawn(img_download, img_url3, "3.gif")])

进程、线程、协程区别

1.进程:资源分配的基本单位,重量级,单独分配内存
2.线程:任务调度的基本单位,本身不拥有资源,占有很少的运行资源
3.协程:微线程,在不创建新线程的基础上,执行多任务

Python高级——协程相关推荐

  1. python高级---协程---放飞自我

    一:定义: 1:协程:微线程(比线程更小) 线程 和 进程 都是CPU调度 协程是开发者自己决定. 优点:效率高,不需要锁. 二:gevent使用: 1:导入库: pip3 install -i ge ...

  2. Python 的协程库 greenlet 和 gevent

    greenlet 官方文档:https://greenlet.readthedocs.io/en/latest/ From:https://www.jianshu.com/u/3ab212f28d91 ...

  3. python gevent 协程

    python gevent 协程 def func1():print("fun1开始运行")gevent.sleep(2) # 内部函数实现io操作print("func ...

  4. Python基础入门教程:使用 Python 3 协程快速获得一个代理池

    Python基础入门教程:使用 Python 3 协程快速获得一个代理池 前言 在执行 IO 密集型任务的时候,程序会因为等待 IO 而阻塞.比如我们使用 requests 库来进行网络爬虫请求的话, ...

  5. python中协程与函数的区别_深入浅析python 协程与go协程的区别

    进程.线程和协程 进程的定义: 进程,是计算机中已运行程序的实体.程序本身只是指令.数据及其组织形式的描述,进程才是程序的真正运行实例. 线程的定义: 操作系统能够进行运算调度的最小单位.它被包含在进 ...

  6. python中协程与函数的区别_python 协程与go协程的区别

    进程.线程和协程 进程的定义: 进程,是计算机中已运行程序的实体.程序本身只是指令.数据及其组织形式的描述,进程才是程序的真正运行实例. 线程的定义: 操作系统能够进行运算调度的最小单位.它被包含在进 ...

  7. Python 的协程

    前言 最近在看部分Python源码时, 发现了async 这个关键字. 查了一下发现了Python中的协程. 协程这玩意, 在GO中我用过啊, 简单说, 就是一个轻量级的线程嘛, 由语言自己来实现不同 ...

  8. python3 协程 写法_理解Python的协程(Coroutine)

    由于GIL的存在,导致Python多线程性能甚至比单线程更糟. GIL: 全局解释器锁(英语:Global Interpreter Lock,缩写GIL),是计算机程序设计语言解释器用于同步线程的一种 ...

  9. python携程使用_简单了解python gevent 协程使用及作用

    简介 没有切换开销.因为子程序切换不是线程切换,而是由程序自身控制,没有线程切换的开销,因此执行效率高, 不需要锁机制.因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断 ...

最新文章

  1. Javascript字符串及数组赋值区别
  2. UICollectionView的headerView、footerView使用以及与UITableView加载headerView、footerView的区别...
  3. python计算输入的两个数字,try...except...判断是否输入的是数字,如果是则相加
  4. HBASE+Solr实现详单查询--转
  5. element ui 批量删除之后动态更新列表_气象编程 | Python高效批量绘图方法
  6. C++访问权限与继承
  7. Docker 持久化存储
  8. [转] 一次Ajax查错的经历
  9. GHOSTXP_SP3电脑公司快速安装机版V2013
  10. ubuntu开机时网络图标不见了且不能上网
  11. Mysql学习总结(71)——MySQL 重复记录查询与删除总结
  12. win7日历加入农历_还是农历更亲切,春节制作一个带农历的日历,欢欢喜喜过新年...
  13. 维基解密:科技公司获得安全漏洞信息须答应几个条件
  14. mysql配置my.cnf文件,以及参数优化提升性能
  15. Spring Boot 集成 RabbitMQ 升级
  16. java正则表达式yyyymmdd_正则表达式校验YYYYMMDD日期格式
  17. cad化气路图_气路图符号cad下载
  18. xampp mysql3306_xmapp_mysql端口冲突解决---Port 3306 in use by......
  19. maya2018 + VS2017 C++编译环境搭建
  20. 使用Cronjobs的综合指南

热门文章

  1. [转]双线性插值(Bilinear interpolation)
  2. python批量下载百度照片
  3. Cenos 7修改时区的方法
  4. CCF201509-4 高速公路(100分)
  5. 【转载】我是一个线程(修订版)
  6. Hotspot JVM的常用选项
  7. vmware 克隆centos 6.4网卡不识别
  8. 【转载】wpf数据绑定binding与INotifyPropertyChanged
  9. linux 文件颜色的含义
  10. QQ空间小秘书 V1.70 Beta1 ~~ 天空原创软件