立即学习:https://edu.csdn.net/course/play/24458/296457?utm_source=blogtoedu

协程(yield,greenlet,gevent)

1.协程:在单线程中通过不断地在多个任务之间进行切换执行,来达到并发的效果的线程,可以提高效率

2.yield实现协程

#yield = return + generator(生成器)
#有yield的函数就是生成器,不会直接执行函数,首先获得生成器对象然后使用next函数这才开始运行函数
#next方法#并发执行
import time
def productor():g = costumor()for i in range(100):res = next(g)print(res)def costumor():for i in range(100):res = yield "*"*5+"%s"%i+'*'*5if __name__ == '__main__':start_time = time.time()productor()end_time = time.time()print('%.9f'%float(end_time-start_time))#串行
def productor():res = costumor()for i in res:print('*'*5+str(i)+"*"*5)def costumor():res=[]for i in range(100):res.append(i)return resif __name__ == '__main__':start_time = time.time()productor()end_time = time.time()print('%.9f'%float(end_time-start_time))

3.greenlet实现协程

#greenlet也是i一个可以实现单线程内并发的效果,但是和yield一样不能检测i/o模型
#切换的格式为:
'''
g1 = greenlet(function1)#获得对象
g2.switch(para)#从当前任务切换到g2对应的任务中
'''
#协程并发
from greenlet import greenlet#定义函数一
def eat(name):print('%s1 is eating'%name)g2.switch('同学')print('%s2 is eating'%name)g2.switch()#定义函数2
def play(name):print('%s1 is playing'%name)g1.switch()print('%s2 is playing'%name)if __name__ == '__main__':g1 = greenlet(eat)g2 = greenlet(play)g1.switch('同学')

4.gevent实现协程


#1.gevent模块是基于greenlet模块的,具有检测自身I/O操作的功能
import gevent,time#定义任务1
def eat(name):print('%s eat 1'%name)#自身的I/O操作。可以被检测出,一旦检测出就自动进行任务·切换gevent.sleep(3)print('%s eat 2'%name)#定义任务2
def play(name):print('%s play 1'%name)gevent.sleep(4)print('%s play 2'%name)start_time = time.time()
#创建gevent对象,只是提交了任务,要想出结果,必须跟join函数配对使用
g1 = gevent.spawn(eat,'john')
g2 = gevent.spawn(play,'lucy')g1.join()
g2.join()
end_time = time.time()
print(end_time-start_time)
'''
运行结果:
john eat 1
lucy play 1
john eat 2
lucy play 2
4.0197389125823975#运行时间接近4秒,即两个任务并发执行的#首先该程序是单线程,只有一个主线程,但是含有两个任务,首先按照代码从上到下执行,
执行到创建对象时,会自动跳转到对应的函数中去,如g1跳到eat函数,执行第一次打印,
检测到自身gevent.sleep()I/O操作后,就自动切换到下一个任务,执行play函数的第一次
打印,后面就是两个任务均处于等待状态,期间一直在两个任务之间切换进行检测,因为eat时间短,
所以先执行eat函数的第二次打印任务,接着就是Play的第二次打印#因此这里实现了单线程两个任务并发的效果
'''#2.gevent模块是基于greenlet模块的,具有检测自身I/O操作的功能,不能检测自身以外的I/O操作,如time.sleep()
import gevent,time#定义任务1
def eat(name):print('%s eat 1'%name)#自身的I/O操作。可以被检测出,一旦检测出就自动进行任务·切换time.sleep(3)print('%s eat 2'%name)#定义任务2
def play(name):print('%s play 1'%name)time.sleep(4)print('%s play 2'%name)start_time = time.time()
#创建gevent对象,只是异步提交了任务,不会等结果的出来,要想出结果,必须跟join函数或者和joinall()配对使用,
g1 = gevent.spawn(eat,'john')
g2 = gevent.spawn(play,'lucy')g1.join()
g2.join()
#gevent.joinall([g1,g2])
end_time = time.time()
print(end_time-start_time)
'''
john eat 1
john eat 2
lucy play 1
lucy play 2
7.019653797149658
#运行时间接近与两个任务I/O操作的时间总和,因此gevent不能检测出自身以为的I/O操作
'''#3.gevent.monkey.patch_all():可以检测到自身以外的I/O操作
import gevent,time
from gevent import monkey
monkey.patch_all()#定义任务1
def eat(name):print('%s eat 1'%name)#自身的I/O操作。可以被检测出,一旦检测出就自动进行任务·切换time.sleep(3)print('%s eat 2'%name)#定义任务2
def play(name):print('%s play 1'%name)time.sleep(4)print('%s play 2'%name)start_time = time.time()
#创建gevent对象,只是提交了任务,要想出结果,必须跟join函数配对使用
g1 = gevent.spawn(eat,'john')
g2 = gevent.spawn(play,'lucy')g1.join()
g2.join()
end_time = time.time()
print(end_time-start_time)
'''
john eat 1
lucy play 1
john eat 2
lucy play 2
4.009758949279785#说明检测到了time.sleep()的I/O操作,自动进行切换,实现了单线程并发的效果
'''

学习笔记(35):Python网络编程并发编程-协程(yield,greenlet,gevent模块)相关推荐

  1. 【黑马-python进阶】---学习笔记(7)---线程、进程、协程、正则表达式

    4 多任务-线程 4.1 多任务介绍 目标 知道多任务概念 多任务和单任务程序的区别 1.多任务解析 操作系统可以同时运行多个任务,现在,多核CPU已经非常普及,但是,即使过去的单核CPU,也可以执行 ...

  2. python从网址爬图片协程_python 用 gevent 协程抓取海量网页

    python作为爬虫利器,抓网页的方式简洁明了.爬成百上千的网页,都可以很快爬完,但是如果网页数量上万呢?速度就不能忍受了. 这是一段爬取页面的函数,用了requests库:1 2 3 4 5impo ...

  3. 学习笔记(19):Python网络编程并发编程-互斥锁

    立即学习:https://edu.csdn.net/course/play/24458/296430?utm_source=blogtoedu 1.互斥锁: 多进程间的内存是相互隔离的,因此其数据也是 ...

  4. 学习笔记(34):Python网络编程并发编程-异步调用与回调机制

    立即学习:https://edu.csdn.net/course/play/24458/296452?utm_source=blogtoedu 1.知识点:(详细见代码注释) 1)同步调用: res1 ...

  5. 学习笔记(33):Python网络编程并发编程-进程池线程池

    立即学习:https://edu.csdn.net/course/play/24458/296451?utm_source=blogtoedu 进程池与线程池: 一般应用在网站上,进程池或线程池最大的 ...

  6. 学习笔记(28):Python网络编程并发编程-死锁与递归锁

    立即学习:https://edu.csdn.net/course/play/24458/296445?utm_source=blogtoedu 1.死锁(Lock()的局限性) 知识点:Lock()只 ...

  7. 学习笔记(18):Python网络编程并发编程-守护进程

    立即学习:https://edu.csdn.net/course/play/24458/296429?utm_source=blogtoedu 守护进程(了解) 1.概念:守护进程是主进程在创建子进程 ...

  8. 学习笔记(09):Python网络编程并发编程-模拟ssh远程执行命令-代码实现

    立即学习:https://edu.csdn.net/course/play/24458/296239?utm_source=blogtoedu 1.服务器端:接收客户端发送的命令,subprocess ...

  9. 学习笔记(08):Python网络编程并发编程-实现服务端可以对多个客户端提供服务

    立即学习:https://edu.csdn.net/course/play/24458/296237?utm_source=blogtoedu 链接循环,一个服务器服务多个客户端, 思路1:服务器一个 ...

最新文章

  1. 2019年1月份访问量超过1千的文章
  2. MongoDB 聚合操作
  3. PHP,操作多个用户,多个线程的session,实现用户登陆状态session值的自动更新
  4. qbuttongroup如何都不选中_全程马拉松,半程马拉松该如何跑?很多人都不知道这些细节...
  5. extern “C“那些事
  6. 惠普179fnw打印机使用说明_惠普179fnw驱动下载
  7. WPS2019中论文数学公式居中,编号右对齐如何操作
  8. 时间序列数据的正态性检验
  9. ABP官方文档(一)【入门介绍】
  10. Oracle19c 出现 ora-12514
  11. Postman 是一个接口测试和 http 请求的神器,非常好用。
  12. 微信小程序自定义导航栏(带汉堡包菜单)
  13. 【mysql】 Windows下使用DOS命令进入MySQL数据库
  14. python tcl tk_如何解决Mac版关于python3.5.X的Tcl/Tk (8.5.9) 的警告?
  15. Jfrog Artifactory安装及备份恢复搭建
  16. 如何学习——让你的学习高效率
  17. Linux系统Ubuntu有什么优点?
  18. Android “退一步”的布局加载优化
  19. PostGIS 3.1.2软件安装详细教程(地图工具篇.8)
  20. 尚硅谷谷粒商城第五天 分类、规格、商品增删改查

热门文章

  1. 2011年9月19日 面试重点:asp.net运行原理和生命周期
  2. 数据库系统原理(第6章:数据库安全与保护)
  3. [6]Windows内核情景分析 --APC
  4. 多线程——实现Runnable接口实现一个多线程
  5. mysql-5.7 持久化统计信息详解
  6. 悖论:早期互联网项目,是否需要技术含量?
  7. 在webpack中使用eslint配置(详细教程)-js教程-PHP中文网
  8. 使用PM2搭建在线vue.js开发环境(以守护进程方式热启动)
  9. Activemq源码、编译、导入idea、源码调试总结
  10. maven setting.xml 中文配置详解(全配置)