设为首页 收藏本站
查看: 647|回复: 0

[经验分享] python协程

[复制链接]

尚未签到

发表于 2018-8-8 13:11:10 | 显示全部楼层 |阅读模式
  基础
  http://yeqianfeng.me/python-yield-expression/
  国外写的通俗易懂的
  http://www.dabeaz.com/coroutines/index.html
  协程的好处,处理io有优势。
  gevent实现协程案例
  多进程+协程下,避开了CPU切换的开销,又能把多个CPU充分利用起来,这种方式对于数据量较大的爬虫还有文件读写之类的效率提升是巨大的。
  多进程+协程的问题,是怎么控制进程池的问题,可以看看gevent.pool这个协程池
  当我们面对如下的环境时,事件驱动模型通常是一个好的选择:
  程序中有许多任务,而且…
  任务之间高度独立(因此它们不需要互相通信,或者等待彼此)而且…
  在等待事件到来时,某些任务会阻塞。
  当应用程序需要在任务间共享可变的数据时,这也是一个不错的选择,因为这里不需要采用同步处理。
  网络应用程序通常都有上述这些特点,这使得它们能够很好的契合事件驱动编程模型。
  协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。因此:
  协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置。
  协程,使用它之前我们先讲讲what/why/how(它是什么/为什么用它/怎么使用它)
  基本认识
  代码
  总结
  计算机分为IO bound 和CPU bound两种类型的task
  基本认识
  参考 http://blog.csdn.net/u014745194/article/details/71657575
  Coroutine
  协程其实可以认为是比线程更小的执行单元。 为啥说他是一个执行单元,因为他自带CPU上下文
  我们可以把一个协程 切换到另一个协程。 只要这个过程中保存或恢复 CPU上下文那么程序还是可以运行的
  协程和线程的差异
  线程切换从系统层面远不止保存和恢复 CPU上下文这么简单
  操作系统为了程序运行的高效性每个线程都有自己缓存Cache等等数据,操作系统还会帮你做这些数据的恢复操作。 所以线程的切换非常耗性能。但是协程的切换只是单纯的操作CPU的上下文,所以一秒钟切换个上百万次系统都抗的住
  协程带来的问题
  目前的协程框架一般都是设计成 1:N 模式。所谓 1:N 就是一个线程作为一个容器里面放置多个协程。 那么谁来适时的切换这些协程?答案是有协程自己主动让出CPU,也就是每个协程池里面有一个调度器, 这个调度器是被动调度的。意思就是他不会主动调度。而且当一个协程发现自己执行不下去了(比如异步等待网络的数据回来,但是当前还没有数据到), 这个时候就可以由这个协程通知调度器,这个时候执行到调度器的代码,调度器根据事先设计好的调度算法找到当前最需要CPU的协程。 切换这个协程的CPU上下文把CPU的运行权交个这个协程,直到这个协程出现执行不下去需要等等的情况,或者它调用主动让出CPU的API之类,触发下一次调度。
  调度器<----协程,调度器---->协程
  协程的好处
  在高IO密集型的程序下很好。但是高CPU密集型的程序下没啥好处
  greenlet版本实现协程案例,看起来好容易
  gevent实现协程案例
  import threading
  import asyncio
  @asyncio.coroutine
  def hello():
  print('Hello world! (%s)' % threading.currentThread())
  yield from asyncio.sleep(1)
  print('Hello again! (%s)' % threading.currentThread())
  loop = asyncio.get_event_loop()
  tasks = [hello(), hello()]
  #loop.run_until_complete(asyncio.wait(tasks))
  for i in tasks:
  loop.run_until_complete(i)
  loop.close()
  从注释这个,可以看出协程的作用了
  asyncio.wait,通过它可以获取一个协同程序的列表,同时返回一个将它们全包括在内的单独的协同程序
  当两个hello方法,放入一个wait中,会同时执行,意味着没有阻塞的部分,会同时执行,然后必须等到阻塞完成后,同时返回,并继续循环。
  import asyncio
  @asyncio.coroutine
  def wget(host):
  print('wget %s...' % host)
  connect = asyncio.open_connection(host, 80)
  reader, writer = yield from connect
  header = 'GET / HTTP/1.0\r\nHost: %s\r\n\r\n' % host
  writer.write(header.encode('utf-8'))
  yield from writer.drain()
  #不甚了解asyncio模块的writer函数, 但是从代码来看, 它是直接写出到TCP连接的, 也就是http的sever端
  while True:
  line = yield from reader.readline()
  yield from asyncio.sleep(1)
  if line == b'\r\n':
  #readline函数如果返回了\r\n就说明这一行是空行;
  break
  print('%s header > %s' % (host, line.decode('utf-8').rstrip()))
  # Ignore the body, close the socket
  writer.close()
  loop = asyncio.get_event_loop()
  tasks = [wget(host) for host in ['www.sina.com.cn', 'www.sohu.com', 'www.163.com']]
  loop.run_until_complete(asyncio.wait(tasks))
  loop.close()
  await是异步等待, 既然你已经知道了控制权会被交出去, 那么就说明他自己是不可能自己恢复的, 必须等待外部程序(python解释器)利用send重新启动切换时的执行现场.
  总结
  协程用自己的话,来说,就是并行执行多个任务,自己定义切换任务的顺序,对于io等待类应用有用。
  反正碰到yield from 理解为阻塞就行了。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-548707-1-1.html 上篇帖子: 6.Python深浅拷贝 下篇帖子: linux 安装python及pymongo
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表