Python 实现协程
协程的概念
协程,又称微线程,纤程。英文名Coroutine。一句话说明什么是线程:协程是一种用户态的轻量级线程。(其实并没有说明白~)
我觉得单说协程,比较抽象,如果对线程有一定了解的话,应该就比较好理解了。
那么这么来理解协程比较容易:
线程是系统级别的,它们是由操作系统调度;协程是程序级别的,由程序员根据需要自己调度。我们把一个线程中的一个个函数叫做子程序,那么子程序在执行过程中可以中断去执行别的子程序;别的子程序也可以中断回来继续执行之前的子程序,这就是协程。也就是说同一线程下的一段代码<1>执行着执行着就可以中断,然后跳去执行另一段代码,当再次回来执行代码块<1>的时候,接着从之前中断的地方开始执行。
比较专业的理解是:
协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。因此:协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置。
yield实现协程
子程序(函数)在执行过程中可以中断去执行别的子程序;别的子程序也可以中断回来继续执行之前的子程序”,那么很容易想到Python的yield,显然yield是可以实现这种切换的。
使用yield实现协程操作例子:
#coding=utf-
#! /usr/bin/env python
# -*- coding:utf- -*-
# Author: "Zing-p"
# Date: // def consumer(name):
print("[%s] 要开始啃骨头了..." % (name))
while True:
bone = yield
print("[%s] 正在啃骨头 %s" % (name, bone)) def producer(obj1, obj2):
obj1.send(None) # 启动obj1这个生成器,第一次必须用None <==> obj1.__next__()
obj2.send(None) # 启动obj2这个生成器,第一次必须用None <==> obj2.__next__()
n =
while n < :
n +=
print("[producer] 正在生产骨头 %s" % n)
obj1.send(n)
obj2.send(n) if __name__ == '__main__':
con1 = consumer("消费者A")
con2 = consumer("消费者B")
producer(con1, con2)
输出:
[消费者A] 要开始啃骨头了...
[消费者B] 要开始啃骨头了...
[producer] 正在生产骨头
[消费者A] 正在啃骨头
[消费者B] 正在啃骨头
[producer] 正在生产骨头
[消费者A] 正在啃骨头
[消费者B] 正在啃骨头
[producer] 正在生产骨头
[消费者A] 正在啃骨头
[消费者B] 正在啃骨头
[producer] 正在生产骨头
[消费者A] 正在啃骨头
[消费者B] 正在啃骨头
[producer] 正在生产骨头
[消费者A] 正在啃骨头
[消费者B] 正在啃骨头
greenlet实现协程
Python的 greenlet就相当于手动切换,去执行别的子程序,在“别的子程序”中又主动切换回来。。。
#! /usr/bin/env python
# -*- coding:utf- -*- from greenlet import greenlet
# greenlet 其实就是手动切换;gevent是对greenlet的封装,可以实现自动切换 def test1():
print("")
gr2.switch() # 切换去执行test2
print("")
gr2.switch() # 切换回test2之前执行到的位置,接着执行 def test2():
print("")
gr1.switch() # 切换回test1之前执行到的位置,接着执行
print("") gr1 = greenlet(test1) # 启动一个协程 注意test1不要加()
gr2 = greenlet(test2) #
gr1.switch()
输出
gevent 实现协程
Gevent 是一个第三方库,可以轻松通过gevent实现协程程,在gevent中用到的主要模式是Greenlet, 它是以C扩展模块形式接入Python的轻量级协程。 Greenlet全部运行在主程序操作系统进程的内部,但它们被协作式地调度。
gevent会主动识别程序内部的IO操作,当子程序遇到IO后,切换到别的子程序。如果所有的子程序都进入IO,则阻塞。
#! /usr/bin/env python3
# -*- coding:utf- -*- import gevent def func1():
print("func1 running")
gevent.sleep() # 内部函数实现io操作
print("switch func1") def func2():
print("func2 running")
gevent.sleep()
print("switch func2") def func3():
print("func3 running")
gevent.sleep()
print("func3 done..") gevent.joinall([gevent.spawn(func1),
gevent.spawn(func2),
gevent.spawn(func3),
])
输出
func1 running
func2 running
func3 running
func3 done..
switch func2
switch func1
Python 实现协程的更多相关文章
- python gevent 协程
简介 没有切换开销.因为子程序切换不是线程切换,而是由程序自身控制,没有线程切换的开销,因此执行效率高, 不需要锁机制.因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断 ...
- 深入理解Python中协程的应用机制: 使用纯Python来实现一个操作系统吧!!
本文参考:http://www.dabeaz.com/coroutines/ 作者:David Beazley 缘起: 本人最近在学习python的协程.偶然发现了David Beazley的co ...
- 关于Python的协程问题总结
协程其实就是可以由程序自主控制的线程 在python里主要由yield 和yield from 控制,可以通过生成者消费者例子来理解协程 利用yield from 向生成器(协程)传送数据# 传统的生 ...
- {python之协程}一 引子 二 协程介绍 三 Greenlet 四 Gevent介绍 五 Gevent之同步与异步 六 Gevent之应用举例一 七 Gevent之应用举例二
python之协程 阅读目录 一 引子 二 协程介绍 三 Greenlet 四 Gevent介绍 五 Gevent之同步与异步 六 Gevent之应用举例一 七 Gevent之应用举例二 一 引子 本 ...
- 【Python】协程
协程,又称微线程,纤程.英文名Coroutine. 协程的概念很早就提出来了,但直到最近几年才在某些语言(如Lua)中得到广泛应用. 子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B,B在 ...
- Python之协程(coroutine)
Python之协程(coroutine) 标签(空格分隔): Python进阶 coroutine和generator的区别 generator是数据的产生者.即它pull data 通过 itera ...
- python的协程和_IO操作
协程Coroutine: 协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行. 注意,在一个子程序中中断,去执行其他子程序,不是函数调用,有点 ...
- python 3 协程函数
python 3 协程函数 1:把函数的执行结果封装好__iter__和__next__,即得到一个迭代器 2:与return功能类似,都可以返回值,但不同的是,return只能返回一次值,而yiel ...
- Python之协程函数
Python之协程函数 什么是协程函数:如果一个函数内部yield的使用方法是表达式形式的话,如x=yield,那么该函数成为协程函数. def eater(name): print('%s star ...
- 多任务-python实现-协程(2.1.11)
多任务-python实现-协程(2.1.11) 23/100 发布文章 qq_26624329 @ 目录 1.概念 2.迭代器 1.概念 协程与子例程一样,协程(coroutine)也是一种程序组件. ...
随机推荐
- HTML输入框的默认显示内容
在某些情况下我们会需要在输入框里默认显示一些内容,比如在登录的时候不在输入框前面显示用户名和密码,直接在输入框里显示,这时只要在input的标签里添加属性 placeholder="用户名 ...
- 使用免费的Let's Encrypt通配符证书 升级我们的网站
Let's Encrypt通配符证书的官方启用日期:2018年3月13日 也就是说,2018年3月13日之后,我们就可以使用Let's Encrypt通配符证书了,当然是免费的. Let's Encr ...
- 机器学习理论基础学习5--- PCA
一.预备知识 减少过拟合的方法有:(1)增加数据 (2)正则化(3)降维 维度灾难:从几何角度看会导致数据的稀疏性 举例1:正方形中有一个内切圆,当维度D趋近于无穷大时,圆内的数据几乎为0,所有的数据 ...
- npm的.npmrc文件在哪里?缓存及全局包文件在什么位置?
npm的.npmrc文件在哪里?缓存及全局包文件在什么位置? npm作为node开发过程中的必备工具,长期使用之后,您可能会想:这些全局安装的node包都放在硬盘里面的哪个地方?配置文件.npmr ...
- win10环境下MySql(5.7.21版本)安装过程
windows10上安装mysql(详细步骤) 2016年09月06日 08:09:34 阅读数:60405 环境:windwos 10(1511) 64bit.mysql 5.7.14 时间:201 ...
- !!【通达信】求教:如何对A股的所有股票按照某个选股指标的某个参数排序? - 理想论坛 中国人气最旺的股票论坛
http://www.55188.com/thread-7152852-1-1.html .401进入指标排序,然后占右键把指标更改为MACD即可.(注意401前投资面有一个点!)
- Lower Power with CPF(三)
常用的一些Lower Power的策略: 1)Clock tree optimization and clock gating:在正常情况下clock信号会一直toggle at the maximu ...
- 【转】Java学习:Java中的线程之线程间的通信
hello各位小伙伴 今天我们来搞一下 线程之间的通信 ( • ̀ω•́ )✧ 让线程按照我们的想法来执行 两个线程间的通信 这是我们之前的线程. 执行效果:谁抢到资源,谁运行~ 实现线程交替执行: ...
- javashop组件开发指南
javashop组件开发指南 1. 概念解释 组件:可以理解为是插件,功能点的一个集合. 插件:是指具体的某个功能. 插件桩:是负责调用插件. 事件:是要决定什么时候执行插件 一个组件是由多 ...
- C++结构体字节对齐
转自:http://www.cnblogs.com/JensenCat/p/4770171.html 这里是头文件结构的定义: 一个非字节对齐结构体_tagTest2 一个字节对齐_tagTest3 ...