协程: 也叫纤程,协程是线程的一种实现,指的是一条线程能够在多任务之间来回切换的一

种实现,对于CPU、操作系统来说,协程并不存在

任务之间的切换会花费时间.目前电脑配置一般线程开到200会阻塞卡顿 .

协程的实现: 协程帮助你记住哪个任务执行到哪个位置上了,并且实现安全的切换

一个任务一旦阻塞卡顿,立刻切换到另一个任务继续执行,保证线程总是忙碌的,更加充

分的利用,

CPU,抢占更多的时间片

一个线程可以由多个协程来实现,协程之间不会产生数据安全问题

协程模块:

greenlet gevent的底层,协程,切换的模块

gevent 直接用的,gevent能提供更全面的功能

(1) 用生成器写生产者消费者模型

# producer 生产者
def producer():
for i in range(10):
yield i
# consumer 消费者
def consumer():
g = producer()
for num in g:
print(num)
consumer()

执行结果:

0
1
2
3
4
5
6
7
8
9

(2) 普通版 greenlet+switch组合 基本实现,只能用switch进行手动切换,

缺陷:不能规避雕io,不能自动实现遇到阻塞就切换.

from greenlet import greenlet
import time
def eat():
print("eat one1")
# 切换到play这个协程中
g2.switch()
time.sleep(1)
print("eat one2")
def play():
print("play one1")
print("play one2")
g1.switch()
g1 = greenlet(eat)
g2 = greenlet(play)
g1.switch()

执行结果

eat one1
play one1
play one2
eat one2

(3) 升级版 gevent+spawn组合 有缺陷,不能够识别time.sleep()

spawn 自动检测阻塞,遇到阻塞就切换,相当于switch 的升级版 

import gevent,time
def eat():
print("eat one1")
time.sleep(1)
print("eat one2")
def play():
print("play one1")
time.sleep(1)
print("play one2")
g1 = gevent.spawn(eat)
g2 = gevent.spawn(play)
# 协程的阻塞也是join
g1.join() # 阻塞直到g1协程执行完毕
g2.join() # 阻塞直到g2协程执行完毕

执行结果:发现者并不是我们我们希望的结果

eat one1
eat one2
play one1
play one2

(4) 进阶版本 用gevent.sleep() 取代time.sleep()

import gevent
def eat():
print("eat one1")
gevent.sleep(1)
print("eat one2")
def play():
print("play one1")
gevent.sleep(1)
print("play one2")
g1 = gevent.spawn(eat)
g2 = gevent.spawn(play)
# 协程的阻塞也是join
g1.join() # 阻塞直到g1协程执行完毕
g2.join() # 阻塞直到g2协程执行完毕

执行结果:问题是解决了,但是看起来怪怪的,改变了原有的time,sleep()语法

eat one1
play one1
eat one2
play one2

(5) 终极解决办法 gevent+spawn +monkey.patch_all()

from gevent import monkey;monkey.patch_all()
import time,gevent
def eat():
print("eat one1")
time.sleep(1)
print("eat one2")
def play():
print("play one1")
time.sleep(1)
print("play one2")
g1 = gevent.spawn(eat)
g2 = gevent.spawn(play)
# 协程的阻塞也是join
g1.join() # 阻塞直到g1协程执行完毕
g2.join() # 阻塞直到g2协程执行完毕

执行结果:perfect 完美!你没有看错,就是这只猴子,老厉害了,解决了所有问题

eat one1
play one1
eat one2
play one2

.

(20)gevent协程的更多相关文章

  1. gevent协程、select IO多路复用、socketserver模块 改造多用户FTP程序例子

    原多线程版FTP程序:http://www.cnblogs.com/linzetong/p/8290378.html 只需要在原来的代码基础上稍作修改: 一.gevent协程版本 1. 导入geven ...

  2. 什么是协程?与线程和进程对比优劣在哪?gevent协程示例代码

      协程 协程,又称微线程,纤程.英文名Coroutine..一句话说明什么是线程:协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在 ...

  3. Python之路-python(Queue队列、进程、Gevent协程、Select\Poll\Epoll异步IO与事件驱动)

    一.进程: 1.语法 2.进程间通讯 3.进程池 二.Gevent协程 三.Select\Poll\Epoll异步IO与事件驱动 一.进程: 1.语法 简单的启动线程语法 def run(name): ...

  4. python2.0_s12_day9_协程&Gevent协程

    Python之路,Day9 - 异步IO\数据库\队列\缓存 本节内容 Gevent协程 Select\Poll\Epoll异步IO与事件驱动 Python连接Mysql数据库操作 协程 1.协程,又 ...

  5. python并发编程之gevent协程(四)

    协程的含义就不再提,在py2和py3的早期版本中,python协程的主流实现方法是使用gevent模块.由于协程对于操作系统是无感知的,所以其切换需要程序员自己去完成. 系列文章 python并发编程 ...

  6. Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就绪,挂起,运行) ,***协程概念,yield模拟并发(有缺陷),Greenlet模块(手动切换),Gevent(协程并发)

    Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就 ...

  7. 比物理线程都好用的C++20的协程,你会用吗?

    摘要:事件驱动(event driven)是一种常见的代码模型,其通常会有一个主循环(mainloop)不断的从队列中接收事件,然后分发给相应的函数/模块处理.常见使用事件驱动模型的软件包括图形用户界 ...

  8. python gevent 协程

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

  9. Gevent协程

    协程 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来 ...

随机推荐

  1. java_BufferedReader的一个应用

    应用来自于我做网页的时候,来读出一个txt文档,由于输出到页面的时候总是没有排版,但是原文件中有换行符,之前是使用的byte数组传输,但是这样无法换行 就使用了BufferedReader,因为它是一 ...

  2. 安装php后无法动态加载库

    安装Apache.mysql.PHP并配置完成后使用phpinfo测试显示正常,但是无法动态增加库 原因:安装PHP后不会生成php.ini文件,但是phpinfo测试正常 解决方法: 1.查看配置文 ...

  3. Git命令行基本操作

    Git--- download网址:https://git-scm.com/downloads 0. 安装Git 网上有很多Git安装教程,如果需要图形界面,windows下建议使用TortoiseG ...

  4. Http协议Status状态代码

    Http协议:Http协议(超文本传输协议)是一个基于请求与响应模式的.无状态的.应用层的协议,常基于TCP的连接方式,绝大多数的Web开发,都是构建在HTTP协议之上的Web应用http请求有三部分 ...

  5. aws cloudwatch监控怎么通过钉钉机器人报警

    最近在完善海外业务在aws服务的CloudWatchh监控,发现CloudWatch报警通知要通过aws的sns服务,直接支持的通道有短信和邮件,但是我们想推到钉钉群里面的群机器人里面这个就要借助aw ...

  6. Delphi数据库技术中Disablecontrols和Enablecontrols的功能

    一般来说,用来扫描整个数据库表并修改每个记录的某一个字段的程序如下所示: with Table Do begin DisableControls;{在修改记录的过程中,使其它部件无效} First; ...

  7. git忽略某些文件的几种方法

    不知道为什么我记得我写过这个内容但是又找不到了,只好照着大致记忆写一下以备留存. 1.首先肯定是.gitignore文件 .gitignore文件适合在文件尚未被追踪时加入,将其忽略便可以不上传到远程 ...

  8. HTTP请求中POST与GET的区别

      本文章已收录于:   一.原理区别 一般我们在浏览器输入一个网址访问网站都是GET请求;再FORM表单中,可以通过设置Method指定提交方式为GET或者POST提交方式,默认为GET提交方式. ...

  9. JS数据类型判断的方法

    最常用的判断方法:typeof var a='isString'; var b=121221; var c=[1,2,3]; var d=new Date(); var e=function(){ c ...

  10. APScheduler(Python化的Cron)使用总结 定时任务

    APScheduler(Python化的Cron)使用总结 简介 APScheduler全程为Advanced Python Scheduler,是一款轻量级的Python任务调度框架.它允许你像Cr ...