""" 协程 """
'''
协程: 类似于一个可以暂停的函数,可以多次传入数据,可以多次返回数据
协程是可交互的
耗资源大小:进程 --> 线程(微进程) --> 协程(微线程)
协程完成通信:生产者与消费者模式--(进程/线程/协程间通信)都可实现
进程/线程/协程 三者之间的关系:
多进程是重开进程
多线程是在进程中开启
协程是在一个进程中的一个线程中开启
协程的执行单元就是函数,(从执行单元上属于并发,对于整个服务器来说并不是)
如果协程阻塞,那么整个进程(线程)也会被阻塞。任意时刻只有一个协程在执行
协程不能避开阻塞, 通过异步的方式避开阻塞
'''
from random import randint
from time import sleep def producer(generator):
while True:
task = randint(1, 100)
generator.send(task)
print('生产了一个任务:', task)
sleep(2) def consumer():
while True:
task = (yield)
print('消费了一个任务:', task) if __name__ == '__main__':
generator = consumer()
next(generator) # 启动生成器, 是consumer阻塞在yield, 才能执行producer中的send方法
producer(generator)

greenlet:  原生的协程包  pip3 install greenlet

  价值一:高性能的原生协程

  价值二:语义更加明确的显示切换

  价值三:直接将函数包装成协程,保持代码风格

''' greenlet协程 '''
from greenlet import greenlet from random import randint def producer():
""" 生产者 """
while True:
item = randint(1, 100)
c.switch(item) # 阻塞并 (转换发送数据)到consumer
print('生产了一个任务:', item) def consumer():
""" 消费者 """
while True:
item = p.switch() # 阻塞并转换到producer
print('消费了一个任务:', item) if __name__ == '__main__':
p = greenlet(producer)
c = greenlet(consumer)
c.switch() # 启动consumer
'''
switch转换工作单元(函数producer和consumer)
'''

gevent:

gevent = epoll(可避开阻塞) + greenlet(不可避开阻塞)
价值一:使用基于epoll的libev来避开阻塞
价值二:使用基于greenlet的高效协程来切换执行
价值三:只有遇到阻塞的时候切换,没有轮询的开销,也没有线程的开销
""" gevent = epoll(可避开阻塞) + greenlet(不可避开阻塞) """
from gevent import monkey; monkey.patch_all() # 猴子补丁, 将socket替换成epoll封装的socket
from gevent.queue import Queue # gevent封装的队列
from random import randint
from time import sleep import socket
import gevent def producer():
while True:
item = randint(0, 100)
queue.put(item)
print('生产了一个任务:', item)
sleep(1) def consumer():
while True:
item = queue.get()
print('消费了一个任务:', item)
sleep(3) def my_worker():
while True:
conn, addr = server.accept()
recv_data = conn.recv(1024)
if recv_data:
conn.send(recv_data)
else:
conn.close()
break server = socket.socket()
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(('', 8000))
server.listen(1000) queue = Queue(3) p = gevent.spawn(producer) # 协程化
c = gevent.spawn(consumer)
# 等待所有协程结束
gevent.joinall(
[p, c]
)

协程,greenlet,gevent的更多相关文章

  1. python 协程 greenlet gevent

    一.并发的本质 切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制),一种情况是该任务发生了阻塞,另外一种情况是该任务计算的时间过长时间片到了 二.协程 ...

  2. 线程队列 concurrent 协程 greenlet gevent

    死锁问题 所谓死锁:是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进 ...

  3. day 34 线程队列 线程池 协程 Greenlet \Gevent 模块

    1 线程的其他方法 threading.current_thread().getName()    查询当前线程对象的名字 threading.current_thread().ident      ...

  4. 协程,greenlet原生协程库, gevent库

    协程简介 协程(coroutine),又称为微线程,纤程,是一种用户级的轻量级线程.协程拥有自己的寄存器上下文和栈. 协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来时,恢复之前保存的上下文 ...

  5. 【python】-- 协程介绍及基本示例、协程遇到IO操作自动切换、协程(gevent)并发爬网页

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

  6. 并发编程(六)——进程/线程池、协程、gevent第三方库

    进程/线程池.协程.gevent第三方库 一.进程/线程池 1.进程池 (1)什么是进程池 如果需要创建的子进程数量不大,可以直接利用multiprocess中的Process来创建.但是当需要创建上 ...

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

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

  8. 协程greenlet、gevent

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

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

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

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

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

随机推荐

  1. Java易错题(1)

    检查程序,是否存在问题,如果存在指出问题所在,如果不存在,说明输出结果. public class HelloB extends HelloA { public HelloB() { } { Syst ...

  2. hadoop 设置回收站

    我的问题是:hadoop回收站为什么会保留多个过期时间的数据   我们知道hadoop的回收站是在我们删除数据后能恢复的目录,但是我们并不希望在回收站保存太久的数据,我们可以使用如下参数进行配置.   ...

  3. python 安装scrapy need vistual c++ 14.0 的正面解法

    为什么一堆教程里面,都是侧面的. 因为需要你自己去正面刚 正题: 这个问题要的是 build tools 人(控制台)说的很清楚了, 给的链接不是直接解决问题的链接(我安装了 vs_redis.exe ...

  4. Python中异常处理

    高级语言通常都配置了一套try...except...finally的错误处理机制. 1.我们先看一个try的机制 try: res=1/0except ZeroDivisionError as e: ...

  5. MacOs 安装cordova报无权访问题解决方案

    在MacOS安装cordova后,执行cordova -v报错: Error: EACCES: permission denied, open '/Users/jianuonuo/.config/co ...

  6. python day20面向对象-属性,类方法,静态方法

    一.属性的初识 # class Person: # # def __init__(self,name,hight,weight): # self.name = name # self.__hight ...

  7. 在linux系统安装tomcat后,bin文件下startup.sh启动不

    Linux里的tomcat下的 bin ,没法执行,   可直接到 bin 目录下 ,执行 chmod 777 *  就可以了. [srmdev@mvxl0793 bin]$ chmod 777  * ...

  8. 实验楼 MySQL 基础课程 挑战:搭建一个简易的成绩管理系统的数据库

    传送门:https://www.shiyanlou.com/courses/running 介绍 现需要构建一个简易的成绩管理系统的数据库,来记录几门课程的学生成绩.数据库中有三张表分别用于记录学生信 ...

  9. python 前端 html

    web 服务本质: 浏览器发出请求--HTTP协议--服务端接收信息----服务端返回响应---服务端把HTML文件发给浏览器--浏览器渲染页面. HTML: 超文本标记语言是一种用于创建网页的标记语 ...

  10. vim中将小写替换为大写--快速解决变量名风格

    将C语言的下划线分割快速替换为Java的驼峰方式. 命令如下 :%s/_\([a-zA-Z]\)/\U\1/g 参考文档