python-多任务编程05-协程(coroutine)
协程是python个中另外一种实现多任务的方式,只不过比线程更小占用更小执行单元(理解为需要的资源)。 为啥说它是一个执行单元,因为它自带CPU上下文。这样只要在合适的时机, 我们可以把一个协程 切换到另一个协程。 只要这个过程中保存或恢复 CPU上下文那么程序还是可以运行的。
通俗的理解:在一个线程中的某个函数,可以在任何地方保存当前函数的一些临时变量等信息,然后切换到另外一个函数中执行,注意不是通过调用函数的方式做到的,并且切换的次数以及什么时候再切换到原来的函数都由开发者自己确定
通过yield实现基础协程
yield的特点就是能够执行方法函数时,暂停执行,然后再继续往下执行,这样就能够实现方法的切换执行
import time def dancing():
for i in range(5):
print('正在跳舞。。。。%d' % i)
yield
time.sleep(0.1) def singing():
for i in range(5):
print('正在唱歌。。。。%d' % i)
yield
time.sleep(0.1) def main():
dance = dancing()
sing = singing()
for i in range(5):
next(dance)
next(sing)
time.sleep(0.1) if __name__ == '__main__':
main()
运行结果为:

通过greenlet实现协程
python中的greenlet模块对yield进行封装,从而使得切换任务变的更加简单,使用前先安装:pip install greenlet
greenlet中先创建对象,然后调用switch()方法开始执行程序
import time
from greenlet import greenlet def dancing():
for i in range(10):
print('正在跳舞。。。。。%d' % i)
sing.switch()
time.sleep(0.1) def singing():
for i in range(10):
print('正在唱歌。。。。。%d' % i)
dance.switch()
time.sleep(0.1) # 创建全局greenlet对象
dance = greenlet(dancing)
sing = greenlet(singing) def main():
# 调用执行dance
print('开始执行dance')
dance.switch() if __name__ == '__main__':
main()
运行结果为:

通过gevent实现协程
greenlet已经实现了协程,但是需要手动通过调用switch进行切换,而gevent模块比greenlet更强大的并且能够自动切换任务。
其原理是当一个greenlet遇到IO(指的是input output 输入输出,比如网络、文件操作等)操作时,比如访问网络,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。
使用前先安装:pip install gevent
gevent的基础使用案例
1.普通的耗时操作写法需要转化为gevent模块中的耗时操作,如time.sleep转化为gevent.sleep
2.使用join()开始执行对象中对应的方法并等待方法执行完成
import gevent
import time def dancing(n):
for i in range(n):
print('正在跳舞...%d' % i)
# time.sleep(0.2)
# 普通的耗时操作,如time.sleep、socket.recv()、socket.connect()等
# 这些代码需要手动转换为gevent模块中对应的方法,才能被gevent认为是耗时操作
# 当gevent遇到了认可的耗时操作后,就会自动切换通过gevent创建的对象
# 若没有遇到耗时操作,则按顺序执行gevent对象
gevent.sleep(0.5) def singing(n):
for i in range(n):
print('正在唱歌...%d' % i)
# time.sleep(0.2)
gevent.sleep(0.5) def main():
print('--------main开始-------')
# 创建对象,这时并没有执行方法里面的代码
dance = gevent.spawn(dancing, 5)
sing = gevent.spawn(singing, 6)
# join()开始执行对象中对应的方法并等待方法执行完成
# 在执行方法的过程中,遇到耗时操作,则自动会切换执行gevent对象中的其他方法。
dance.join()
sing.join()
print('-------main结束--------') if __name__ == '__main__':
main()
运行结果为:

gevent的常用简洁写法
1.导入gevent中的monkey,可以将程序中的普通耗时操作转换为gevent中认可的耗时操作
2.使用gevent.joinall让程序更加简洁
import gevent
from gevent import monkey
import time # 有耗时操作时,需要执行这句话
# 能将普通的耗时操作转换为gevent中的耗时操作,这样就不用手动把耗时操作全都替换成gevent中对应的耗时操作了
monkey.patch_all() def work(name, num):
for i in range(num):
print('%s正在执行。。。。%d' % (name, i))
time.sleep(0.2) def main():
dance = gevent.spawn(work, '小明', 5)
sing = gevent.spawn(work, '小花', 6)
gevent.joinall([dance, sing]) if __name__ == '__main__':
main()
运行结果为:

python-多任务编程05-协程(coroutine)的更多相关文章
- 32 python 并发编程之协程
一 引子 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去 ...
- 四 python并发编程之协程
一 引子 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去 ...
- 第十篇.5、python并发编程之协程
一 引子 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去 ...
- 第 12 章 python并发编程之协程
一.引子 主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只用一个)情况下实现并发,并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作 ...
- 37、python并发编程之协程
目录: 一 引子 二 协程介绍 三 Greenlet 四 Gevent介绍 五 Gevent之同步与异步 六 Gevent之应用举例一 七 Gevent之应用举例二 一 引子 本节的主题是基于单线程来 ...
- python网络编程之协程
本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去执行其他的 ...
- python并发编程之协程(实践篇)
一.协程介绍 协程:是单线程下的并发,又称微线程,纤程.一句话说明什么是线程:协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的. 对于单线程下,我们不可避免程序中出现io操作,但如果我们 ...
- python并发编程之协程知识点
由线程遗留下的问题:GIL导致多个线程不能真正的并行,CPython中多个线程不能并行 单线程实现并发:切换+保存状态 第一种方法:使用yield,yield可以保存状态.yield的状态保存与操作系 ...
- python 并发编程之协程
一.协程 协程: 单线程下的并发,又称 微线程.协程是一种用户态的的轻量级线程,即协程是由用户程序自己控制调度的. 协程的本质就是在单线程下,由用户自己控制一个任务,遇到 io 阻塞就切换另外一个 ...
- python并发编程之协程
---恢复内容开始--- 一.join方法 (1)开一个主线程 from threading import Thread,currentThread import time def walk(): p ...
随机推荐
- ant +jmeter+jenkins接口自动化测试二
[Jmeter篇]Jmeter+Ant+Jenkins接口自动化测试集成之半路逆转(二) 橙子探索测试发表于橙子探索测试订阅 72 [Jmeter篇]jmeter+Ant+Jenkins接口自动化测试 ...
- dart快速入门教程 (1)
1.环境搭建 1.1.dart简介 Dart 是一种 易于学习. 易于扩展.并且可以部署到 任何地方 的 应用 编程 语言.Google 使用 Dart 来开发 大型应用.flutter使用dart语 ...
- dubbo源码解析之负载均衡
在分布式系统中,负载均衡是必不可少的一个模块,dubbo 中提供了五种负载均衡的实现,在阅读这块源码之前,建议先学习负载均衡的基础知识.把看源码当做一个印证自己心中所想的过程,这样会得到事半功倍的效果 ...
- 如何查看class文件的jdk版本
版权声明:本文为博主原创文章,转载请注明本文链接.文章内容如有错误望能指正,以免误导更多人. https://blog.csdn.net/gnail_oug/article/details/47145 ...
- java中的Arrays这个工具类你真的会用吗
Java源码系列三-工具类Arrays 今天分享java的源码的第三弹,Arrays这个工具类的源码.因为近期在复习数据结构,了解到Arrays里面的排序算法和二分查找等的实现,收益匪浅,决定研读 ...
- Maven中央仓库正式成为Oracle官方JDBC驱动程序组件分发中心
1. 前言 相信参与使用Oracle数据库进行项目开发.运维的同学常常被Oracle JDBC驱动的Maven依赖折磨.现在这一情况在今年二月份得到了改变,甲骨文这个老顽固终于开窍了. 一位甲骨文的工 ...
- 每天一个LINUX命令(pwd)
每天一个LINUX命令(pwd) 基本信息 pwd: /bin/pwd,显示当前路径的绝对路径 语法:pwd 应用程序位置 which pwd PWD作用 pwd --help ...
- 【盗版动归】Codeforces998C——Convert to Ones 归一操作
嘤嘤嘤,因为最近文化课老师追的紧了+班主任开班会,所以这博客是赶制的赝品 题目: You've got a string a1,a2,…,ana1,a2,…,an, consisting of zer ...
- mac篇---mac安装jupyter
1.Jupyter搭建 pip install --user jupyter 如果是在python3中,则用如下命令: pip3 install --user jupyter 如下图所示: 2. Ju ...
- H3c实验室-(OSPF,Nat,STP,Dhcp,Acl)v.1)
实验声明 本实验纯属学习记录性质,如有错误,请大哥帮忙提出,马上改正谢谢~还有学习H3c心态要好,他有超级多的bug!!!! 实验介绍 实验条件 实验开始 把图设计好 先说明一下RTA-RTB的线路是 ...