1、greenlet模块:实现20个任务切换

如果我们在单个线程内有20个任务,要想实现在多个任务之间切换,使用greenlet模块可以非常简单地实现这20个任务直接的切换
使用yield生成器的方式过于麻烦(需要先得到初始化一次的生成器,然后再调用send。。。非常麻烦)

  

(1)switch 开关:执行greenlet对象

# 一个线程里面有20个任务,实现在多个任务之间切换
# pip install greenlet # 安装失败 from greenlet import greenlet # eta
def eat(name):
print('%s eat 1' % name)
print('%s eat 2' % name) def play(name):
print('%s play 1' % name)
print('%s play 2' % name) g1 = greenlet(eat) # 创建一个greenlet对象
g2 = greenlet(play) g1.switch('alex') # 开关: run greenlet对象

  (2)g2.switch():接着上次的阻塞继续执行

  (2)等待2s,阻塞中,不切换

greenlet只是提供了一种比generator更加便捷的切换方式,当切到一个任务执行时如果遇到io,那就原地阻塞,仍然是没有解决遇到IO自动切换来提升效率的问题。

  

2、gevent模块:阻塞也切换

单线程里的这20个任务的代码通常会既有计算操作又有阻塞操作,我们完全可以在执行任务1时遇到阻塞,就利用阻塞的时间去执行任务2。。。。如此,才能提高效率,这就用到了Gevent模块。

  

  (1)用法

g1=gevent.spawn(func,1,,2,3,x=4,y=5)
#创建一个协程对象g1,
spawn括号内第一个参数是函数名,如eat,
后面可以有多个参数,可以是位置实参或关键字实参,都是传给函数eat的
g2=gevent.spawn(func2) g1.join() #等待g1结束
g2.join() #等待g2结束 #或者上述两步合作一步:
gevent.joinall([g1,g2]) g1.value #拿到func1的返回值

  (2)遇到IO阻塞时会自动切换任务

gevent.sleep(2)模拟的是gevent可以识别的io阻塞

  (3)不能识别其他阻塞:time.sleep(2)

  (4)from gevent import monkey;monkey.patch_all()

而time.sleep(2)或其他的阻塞,gevent是不能直接识别的
需要用下面一行代码,打补丁,就可以识别了from gevent import monkey;monkey.patch_all()必须放到被打补丁者的前面,如time,socket模块之前
或者我们干脆记忆成:要用gevent,需要将from gevent import monkey;monkey.patch_all()放到文件的开头

  

import gevent  # 实现并发同步与异步编程
import time
from gevent import monkey; monkey.patch_all() # 识别其他的阻塞 def eat(name):
print('%s eat 1' % name)
time.sleep(2) # 遇到阻塞时会自动切换任务
print('%s eat 2' % name) def play(name):
print('%s play 1' % name)
time.sleep(3)
print('%s play 2' % name) start_time = time.time()
g1 = gevent.spawn(eat, 'akex')
g2 = gevent.spawn(play, 'jack') g1.join()
g2.join() print('<%s>' % (time.time()-start_time))

我们可以用threading.current_thread().getName()来查看每个g1和g2,查看的结果为DummyThread-n,即假线程

  

3、gevent异步提交任务

  (1)创建未执行,程序就结束了

  (2)主:sleep 1s

 

  (3)主sleep 5s

  (4)g2.join()

import gevent
import time
from gevent import monkey; monkey.patch_all() # 识别其他的阻塞 def eat(name):
print('%s eat 1' % name)
time.sleep(2) # 遇到阻塞时会自动切换任务
print('%s eat 2' % name) def play(name):
print('%s play 1' % name)
time.sleep(3)
print('%s play 2' % name) g1 = gevent.spawn(eat, 'akex')
g2 = gevent.spawn(play, 'jack') # g1.join() # g1完成 g2不会完成
g2.join() # 由于g2需要花费3s,g1花费2s。 因此只需要等待g2完成即可,g1会提前完成

  

4

5

10-[协程] greenlet模块、 gevent模块的更多相关文章

  1. 网络编程基础--协程--greenlet切换---gevent自动识别 IO ---

    协程: 1 单线程来实现并发---协程: 协程:是单线程下的并发,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程, 即协程是由用户程序自己控制调度的 只 ...

  2. 协程greenlet、gevent

    greenlet为了更好使用协程来完成多任务,python中greenlet模块对其封装,从而使得切换任务变得更加简单安装方式 pip3 install greenlet 示例代码: from gre ...

  3. Python的requests、greenlet和gevent模块在windows下安装

    一.requests模块在windows下安装 Linux系统下requests的安装方法在http://docs.python-requests.org/en/latest/user/install ...

  4. python 线程(其他方法,队列,线程池,协程 greenlet模块 gevent模块)

    1.线程的其他方法 from threading import Thread,current_thread import time import threading def f1(n): time.s ...

  5. 协程----greenlet模块,gevent模块

    1.协程初识,greenlet模块 2.gevent模块(需要pip安装) 一.协程初识,greenlet模块: 协程:是单线程下的并发,又称微线程,纤程.英文名Coroutine.一句话说明什么是线 ...

  6. python 全栈开发,Day43(引子,协程介绍,Greenlet模块,Gevent模块,Gevent之同步与异步)

    昨日内容回顾 I/O模型,面试会问到I/O操作,不占用CPU.它内部有一个专门的处理I/O模块.print和写log 属于I/O操作,它不占用CPU 线程GIL保证一个进程中的多个线程在同一时刻只有一 ...

  7. Python之路(第四十七篇) 协程:greenlet模块\gevent模块\asyncio模块

    一.协程介绍 协程:是单线程下的并发,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的. 协程相比于线程,最大的区别在于 ...

  8. 协程介绍, Greenlet模块,Gevent模块,Genvent之同步与异步

    昨日内容回顾 I/O模型,面试会问到I/O操作,不占用CPU.它内部有一个专门的处理I/O模块.print和写log 属于I/O操作,它不占用CPU 线程GIL保证一个进程中的多个线程在同一时刻只有一 ...

  9. 14 并发编程-(协程)-greenlet模块&gevent模块

    1.实现多个任务之间进行切换,yield.greenlet都没有实现检测I/O,greenlet在实现多任务切换下更简单 from greenlet import greenlet def eat(n ...

  10. 并发编程~~~协程~~~greenlet模块, gevent模块

    一 协程 1. 协程: 单线程下的并发,又称微线程,纤程.协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的. 并发真正的核心: 切换并且保持状态. 开启协程并发的执行,自己的程序把控着C ...

随机推荐

  1. The operation names in the portType match the method names in the SEI or Web service implementation class.

    The Endpoint validation failed to validate due to the following errors: :: Invalid Endpoint Interfac ...

  2. 委托学习总结(二)匿名方法和lambda表达式

    之前总结了委托这个困惑着大多初学者的概念,继续来学习匿名方法和lambda表达式 (1)我们之前写了这样一段代码 //自定义一个委托 public delegate int Expression(in ...

  3. Custom Settings.ini 和 bootstrap.ini 配置

    [Settings]Priority=DefaultProperties=MyCustomProperty [Default] ;SkipWizard=YES 如果跳过部署向导,则即使 SkipCap ...

  4. Linux 系统学习梳理_【All】

    第一部分---基础学习 00.Linux操作系统各版本ISO镜像下载 00.Linux系统下安装Vmware(虚拟机) 00.Linux 系统安装[Redhat] 00.Linux 系统安装[Cent ...

  5. ssh连接CentOS7服务器

    ssh原理: ssh是一种专为远程登陆会话和其他网络服务提供安全性的协议,主要用于远程登陆. ssh采用公钥加密,在远程连接时,远程主机接收到用户的登录请求,将自己的公钥发送给用户,用户使用这个公钥将 ...

  6. 快速搭建一个Express工程骨架

    下载express-generator 通过应用生成器,可以帮我们快速搭建项目需要的骨架.这就需要npm在全局下载express-generator(-g就是在全局安装) npm install ex ...

  7. EF 实体类的制定属性不生成数据库字段

    添加一个标签即可 [NotMapped] 没什么营养,就是防忘记

  8. PHP设计模式系列 - 建造者模式

    什么是建造者模式 建造者模式主要是为了消除其它对象复杂的创建过程. 设计场景 有一个用户的UserInfo类,创建这个类,需要创建用户的姓名,年龄,金钱等信息,才能获得用户具体的信息结果. 创建一个U ...

  9. Spring 读取配置文件的俩种方式

    读取配置可通过 org.springframework.core.env.Environment 类来获取, 也可以通过@Value的方式来获取 注解形式: @PropertySource({&quo ...

  10. Django之Model (ORM)

    传统操作数据库 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去调用数据访问层 ...