python中协程

协程是python中除了进程和线程之外又一种能够实现多任务的方式,又称为微线程,纤程,它相比于线程需要的资源更少。

在python种协程是通过generator实现的。通过yield保存当前运行的状态然后切换到另一个协程执行。普通的生产者-消费这模式是一个线程写消息,一个线程才能读取消息,因此需要控制队列的写入与读取数据。而改用协程可以在生产者生产消息后直接通过yield跳转到消费者开始执行,执行完毕后在切换到生产者,如此反复,效率极高。

在图中,我们可以看出通过next的方法使得生成器中的任务完成了交替执行,实现了多任务。

注意,在协程模拟中,相较于线程没法设计运行顺序,协程是可以设计执行的顺序的。这样协程之间就能协作完成任务,而不会如线程一样得抢占资源。

由于协程得切换只是简单得操作CPU得上下文,因此系统甚至在1s中切换几百万次都毫无压力。

在python中为了更好得使用协程来完成任务,可以使用python中greenlet模块和gevent。greenlet在协程切换需要人工切换,因此主要给大家介绍gevent这个强大且能自动切换任务的模块。

在讲解gevent模块直接,大家需要先了解一下协程主要发力的领域,那就是异步IO。

我们都知道CPU得执行速度很快,每秒几百万次几千万次得速度小菜一碟。在IO操作得时候,如读写文件,发送网络数据等,都需要等待IO操作才能执行下面的代码,这种情况就叫做同步IO。在IO操作得过程中,当前的线程是被挂起的,下面的代码需要等待IO操作完成才能执行。如网络通信send数据,和recv数据得过程实际上都在等待服务器回应。这个时候就需要使用多线程或多进程来并发执行代码,但是,线程和进程得开销很大,如果需要切换的次数较多,反而降低了效率。所以我们为了能够充分利用线程阻塞得这段时间继续使CPU工作(要知道被阻塞1s中CPU就少计算几百万次),可以使用异步IO的方法:当代码执行到一个IO操作得时候,它只发出IO指令,并不等待结果,而去执行其他得代码,当IO响应的时候在返回处理,这样当有频繁得IO操作得时候,将会大大增加程序得执行效率。

直到异步IO得概念后,gevent的原理就很好理解了。我们还是以程序为例

在work这个方法中,用gevent.sleep(1)来模拟线程阻塞1s的情况,从 程序结果可以看出,当线程遇到阻塞会执行下个协程,等到阻塞结束才会回去处理

时间: 2024-10-01 06:39:12

python中协程的相关文章

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

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

Python中协程的实现

通过关键字yield,可以从生成器中产生值,并返回.我们可以将生成器作为一个生产者来使用. 在协程中,通过使用关键字yield,还可以让具有yield的程序接收值.此时函数作为消费者,消费我们传入(send)的值. 在协程中,可以把yield作为右值来用.在foo函数中,我们这样写: n = yield 可以通过send方法来向foo函数发送值,这时,发送的值被foo接收,并存到n里. n中的值可以在foo函数中使用 这样,yield作为右值来使用,就使得foo函数变成了一个消费者. 我们知道,

python gevent 协程

简介 没有切换开销.因为子程序切换不是线程切换,而是由程序自身控制,没有线程切换的开销,因此执行效率高, 不需要锁机制.因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多 Python对协程的支持还非常有限,用在generator中的yield可以一定程度上实现协程. yield 传统的生产者-消费者模型是一个线程写消息,一个线程取消息,通过锁机制控制队列和等待,但一不小心就可能死锁. 如果改用协程,生产者生产消息后,直接通过y

【Python】协程

协程,又称微线程,纤程.英文名Coroutine. 协程的概念很早就提出来了,但直到最近几年才在某些语言(如Lua)中得到广泛应用. 子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B,B在执行过程中又调用了C,C执行完毕返回,B执行完毕返回,最后是A执行完毕. 所以子程序调用是通过栈实现的,一个线程就是执行一个子程序. 子程序调用总是一个入口,一次返回,调用顺序是明确的.而协程的调用和子程序不同. 协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当

Python与协程从Python2—Python3

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

Python之协程函数

Python之协程函数 什么是协程函数:如果一个函数内部yield的使用方法是表达式形式的话,如x=yield,那么该函数成为协程函数. def eater(name): print('%s start to eat food' %name) food_list=[] while True: food=yield food_list print('%s get %s ,to start eat' %(name,food)) food_list.append(food) print('done')

关于Python的协程问题总结

协程其实就是可以由程序自主控制的线程 在python里主要由yield 和yield from 控制,可以通过生成者消费者例子来理解协程 利用yield from 向生成器(协程)传送数据# 传统的生产者-消费者是一个线程写消息,一个线程取消息,通过锁机制控制队列和等待,但一不小心就可能死锁.# 如果改用协程,生产者生产消息后,直接通过yield跳转到消费者开始执行,待消费者执行完毕后,换回生产者继续生产,效率极高 def consumer(): r = '' while True: n = y

python之协程与IO操作

协程 协程,又称微线程,纤程.英文名Coroutine. 协程的概念很早就提出来了,但直到最近几年才在某些语言(如Lua)中得到广泛应用. 子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B,B在执行过程中又调用了C,C执行完毕返回,B执行完毕返回,最后是A执行完毕. 所以子程序调用是通过栈实现的,一个线程就是执行一个子程序. 子程序调用总是一个入口,一次返回,调用顺序是明确的.而协程的调用和子程序不同. 协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,

python之协程

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