【PYTHON模块】:协程与greenlet、gevent

协程:又称为微线程,英文名称Coroutine。

作用:它拥有自己的寄存器上下文和栈,能保留上一次调用时的状态,可以随时暂停程序,随时切换回来。

优点:

?无需线程上下文切换的开销
    ?无需原子操作锁定及同步的开销  

?方便切换控制流,简化编程模型
    ?高并发+高扩展性+低成本:一个CPU支持上万的协程都不是问题。所以很适合用于高并发处理

缺点:
    ?无法利用多核资源:协程的本质是个单线程,它不能同时将 单个CPU 的多个核用上,协程需要和进程配合才能运行在多CPU上
    ?进行阻塞(Blocking)操作(如IO时)会阻塞掉整个程序

  • 使用yield实现协程:
def g(name):
 print("starting product ....")
 while True:
  baozi= yield  # 程序暂停等待next
  print("{} is eating {}...".format(name,baozi))
def p():
 conn.__next__()  # 实例conn启动yield
 conn2.__next__() # 实例conn2启动yield
 i = 0
 while i<5:
  i += 1
  print("product: {}".format(i))  
  conn.send(i) # 向yield发送数据,yield恢复,并自动执行next
  conn2.send(i) # 向yield发送数据,yield恢复,并自动执行next

conn = g("laoda")  # 创建实例conn
conn2 = g("laoer")      # 创建实例conn2
product = p()   # 启动函数p
  • 使用greenlet实现协程:不是python自带模块,需要安装

创建协程对象的方法其实有两个参数”greenlet(run=None, parent=None)”。参数”run”就是其要调用的方法,比如上例中的函数test1()和test2();参数”parent”定义了该协程对象的父协程,也就是说,greenlet协程之间是可以有父子关系的。如果不设或设为空,则其父协程就是程序默认的”main”主协程。

from greenlet import greenlet
def test1():
    print(1)
    t2.switch()    # 函数暂停,切换到t2
    print(2)

def test2():
    print(3)
    t1.switch()    # 函数暂停,切换到t1
    print(4)
   
t1=greenlet(test1)    # test1生成greenlet对象
t2=greenlet(test2)    # test2生成greenlet对象
t1.switch()
  • 使用gevent实现协程:第三方库,需要安装

实现了异步I/O,操作

方法 参数 作用 示例
spawn(func,func_args)
func:加入gevent的函数名

func_args:函数参数

把函数,创建协程实例
joinall[spawn_list] spawn_list:spawn方法列表
把创建的协程实例添加到异步列表

等待列表中的所有实例执行完毕

sleep(time) time:时间(秒) 交出CPU控制权,时间为秒
getcurrent() 获取当前协程内存地址
from gevent import gevent
import random
def creat(num):
 wait_time = random.Randomint(0,num)
 gevent.sleep(wait_time)
 print("{} wait done!".format(gevent.getcrrent()))
 
gevent_list = []
for i in range(20):
 gevent_list.append(gevent.spawn(creat, i))
gevent.joinall(gevent_list)

#Socket并发:(未测试)
import gevent
import socket
class server(object):
 def __int__(self,ip,port,*args):
  self.server_in = socket.socket()
  self.server_in.bind(ip,port)
  self.server_in.listen(100)
  # self.spawn_list = []
  
 def run(self):
  client_spawn = []
  while True:
   conn,addr = self.server_in.accept()
   client_spawn.append(gevent.spawn(handler,conn))
  gevent.joinall(client_spawn)
  
  
 def handler(self,conn):
  while True:
   recv_data = conn.recv(1024)
   if recv_data = 'exit':
    conn.shutdown(socket.SHUT_WR)
    break
   print("recv:".format(recv_data))
   conn.send(recv_data.upper())

http://python.jobbole.com/86481/

协程详解

原文地址:http://blog.51cto.com/yishi/2135547

时间: 2024-10-19 22:43:47

【PYTHON模块】:协程与greenlet、gevent的相关文章

(并发编程)进程池线程池--提交任务的2种方式、协程--yield greenlet,gevent模块

一:进程池与线程池(同步,异步+回调函数)先造个池子,然后放任务为什么要用"池":池子使用来限制并发的任务数目,限制我们的计算机在一个自己可承受的范围内去并发地执行任务池子内什么时候装进程:并发的任务属于计算密集型池子内什么时候装线程:并发的任务属于IO密集型 #提交任务的两种方式:    # 同步调用:提交完一个任务之后,就在原地等待,等待任务完完整整地运行完毕拿到结果后,再执行下一行代码,会导致任务是串行执行的    # 异步调用:提交完一个任务之后,不在原地等待,结果???,而是

python全栈开发基础【第二十六篇】(concurrent.futures模块、协程、Greenlet、Gevent)

注意 1.不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 2.只要你用并发,就会有锁的问题,但是你不能一直去自己加锁吧那么我们就用QUEUE,这样还解决了自动加锁的问题由Queue延伸出的一个点也非常重要的概念.以后写程序也会用到这个思想.就是生产者与消费者问题 一.Python标准模块--concurrent.futures(并发未来) concurent.future模块需要了解的 1.concurent

协程:Greenlet模块、Gevent模块

三.Greenlet模块 Greenlet是python的一个C扩展,来源于Stackless python,旨在提供可自行调度的'微线程', 即协程.generator实现的协程在yield value时只能将value返回给调用者(caller). 而在greenlet中,target.switch(value)可以切换到指定的协程(target), 然后yield value.greenlet用switch来表示协程的切换,从一个协程切换到另一个协程需要显式指定. 安装 :pip3 ins

Python3学习之路~10.2 协程、Greenlet、Gevent

一 协程 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈.因此: 协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置. 协程的好处: 无需线程上下文切换的开销 无需原子操作锁定及同步的开销 "原子操作(atomic

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

yield表达式 在了解协程之前,需要先了解一下生成器中的yield,它不仅可以当做生成器,还能当做一个表达式来使用(yield) def func(): x = (yield) print(x) x = (yield) g = func() print(next(g)) # 这是第一个yield,就暂停了 g.send('hello world') # 恢复暂停位置,将第一个yield赋值, # x = hello world,然后又执行到yield,暂停 --> None hello wor

python中协程

协程是python中除了进程和线程之外又一种能够实现多任务的方式,又称为微线程,纤程,它相比于线程需要的资源更少. 在python种协程是通过generator实现的.通过yield保存当前运行的状态然后切换到另一个协程执行.普通的生产者-消费这模式是一个线程写消息,一个线程才能读取消息,因此需要控制队列的写入与读取数据.而改用协程可以在生产者生产消息后直接通过yield跳转到消费者开始执行,执行完毕后在切换到生产者,如此反复,效率极高. 在图中,我们可以看出通过next的方法使得生成器中的任务

python之协程

协程,又称微线程,纤程.英文名Coroutine.协程是一种用户态的轻量级线程. 所谓用户态就是说协程是由用户来控制的,CPU不认识协程,协程是跑在线程中的. 协程拥有自己的寄存器上下文栈.协程调试切换时,将寄存器上下文栈保存到其他地方,在切回来时,恢复先前保存的寄存器上下文栈. 因此,协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,也就是进入上一次离开时所处逻辑流的位置. 线程切换时会将上下文和栈保存到CPU的寄存器中. 协程的标准定

python学习-----协程

一.协程的引入 对于单线程下,我们不可避免程序中出现io操作,但如果我们能在自己的程序中(即用户程序级别,而非操作系统级别)控制单线程下的多个任务能在一个任务遇到io阻塞时就切换到另外一个任务去计算,这样就保证了该线程能够最大限度地处于就绪态,即随时都可以被cpu执行的状态,相当于我们在用户程序级别将自己的io操作最大限度地隐藏起来,从而可以迷惑操作系统,让其看到:该线程好像是一直在计算,io比较少,从而更多的将cpu的执行权限分配给我们的线程. 协程的本质就是在单线程下, 由用户自己控制一个任

Python与协程从Python2—Python3

协程,又称微线程.纤程,英文名Coroutine:用一句话说明什么是线程的话:协程是一种用户态的轻量级线程. Python对于协程的支持在python2中还比较简单,但是也有可以使用的第三方库,在python3中开始全面支持,也成为python3的一个核心功能,很值得学习. 协程介绍 协程,又称微线程.纤程,英文名Coroutine:用一句话说明什么是线程的话:协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先

深入理解Python中协程的应用机制: 使用纯Python来实现一个操作系统吧!!

本文参考:http://www.dabeaz.com/coroutines/   作者:David Beazley 缘起: 本人最近在学习python的协程.偶然发现了David Beazley的coroutine课程,花了几天时间读完后,为了加深理解就把其中个人认为最为精华的部分摘下来并加上个人理解写了本篇博客. 扯一些淡: 既然要搞一个操作系统,那我们就先来设一个目标吧!就像找女朋友,我们不可能随随便便的是个女的就上,肯定要对女方有一定的要求,比如肤白貌美气质佳…… 所以,我们对这个' 姑娘