单线程下实现IO切换
1、Greenlet
greenlet可以实现两个任务之间的来回切换,但遇到IO会阻塞,不会切(使用这个模块之前需要在电脑命令提示符中输入 pip3 install greenlet 进行安装)
例如:
from greenlet import greenlet
import time def eat(name):
print('%s eat 1' %name)
time.sleep(30) #遇到IO不会切
g2.switch('alex')
print('%s eat 2' %name)
g2.switch()
def play(name):
print('%s play 1' %name)
g1.switch()
print('%s play 2' %name) g1=greenlet(eat)
g2=greenlet(play) g1.switch('egon')
打印结果:
egon eat 1
alex play 1
egon eat 2
alex play 2
2、gevent
先在命令提示符中输入 pip3 install gevent 进行安装
Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,它遇到IO阻塞时会自动切换任务。
#用法
g1=gevent.spawn(func,1,,2,3,x=4,y=5)创建一个协程对象g1,spawn括号内第一个参数是函数名,如eat,后面可以有多个参数,
可以是位置实参或关键字实参,都是传给函数eat的
g2=gevent.spawn(func2)
g1.join() #等待g1结束
g2.join() #等待g2结束
#或者上述两步合作一步:gevent.joinall([g1,g2])
g1.value#拿到func1的返回值
import gevent def eat(name):
print('%s eat 1' %name)
gevent.sleep(5)
print('%s eat 2' %name)
def play(name):
print('%s play 1' %name)
gevent.sleep(3)
print('%s play 2' %name) g1=gevent.spawn(eat,'egon')
g2=gevent.spawn(play,'alex') # gevent.sleep(100)
# g1.join()
# g2.join()
gevent.joinall([g1,g2]) 打印结果:
egon eat 1
alex play 1
alex play 2
egon eat 2
上例gevent.sleep(2)模拟的是gevent可以识别的io阻塞,
而time.sleep(2)或其他的阻塞,gevent是不能直接识别的需要用下面一行代码,打补丁,就可以识别了
from gevent import monkey;monkey.patch_all()必须放到被打补丁者的前面,如time,socket模块之前
或者我们干脆记忆成:要用gevent,需要将from gevent import monkey;monkey.patch_all()放到文件的开头
monkey.patch_all(),相当于把这个程序里只要涉及到IO操作的都打了一个标记,这样可以识别time模块下的IO行为。
from gevent import monkey;monkey.patch_all()
import gevent
import time def eat(name):
print('%s eat 1' %name)
time.sleep(5)
print('%s eat 2' %name)
def play(name):
print('%s play 1' %name)
time.sleep(3)
print('%s play 2' %name) g1=gevent.spawn(eat,'egon')
g2=gevent.spawn(play,'alex') # gevent.sleep(100)
# g1.join() 保证主线程不死掉
# g2.join()
gevent.joinall([g1,g2]) 运行结果和上面程序的结果相同
使用current_thread 可以看线程名
from gevent import monkey;monkey.patch_all()
from threading import current_thread
import gevent
import time def eat():
print('%s eat 1' %current_thread().name)
time.sleep(5)
print('%s eat 2' %current_thread().name)
def play():
print('%s play 1' %current_thread().name)
time.sleep(3)
print('%s play 2' %current_thread().name) g1=gevent.spawn(eat)
g2=gevent.spawn(play) # gevent.sleep(100)
# g1.join()
# g2.join()
print(current_thread().name)
gevent.joinall([g1,g2]) 打印结果:
MainThread
DummyThread-1 eat 1
DummyThread-2 play 1
DummyThread-2 play 2
DummyThread-1 eat 2
注:DummyThread-1,和DummyThread-2是两个假线程,干活的其实都还是主线程在干,没有开过新的线程
spawn提交任务的方式是异步提交,提交完之后不会等在原地,再接着提交下一个任务
学完gevent模块后,可以这样实现并发:
1、开多个进程,用上了多核优势
2、每个进程里再开线程,提高了并发数
3、每个线程使用gevent模块方式实现遇到IO切,把单个线程的效率提到最高
这样做极大的提升了程序的效率
单线程下实现IO切换的更多相关文章
- 异步、+回调机制、线程queue、线程Event、协程、单线程实现遇到IO切换
# from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor # import requests # import o ...
- gevent监测单线程下的io进行切换
from gevent import monkey;monkey.patch_all() import gevent import time def eat(name): print('%s eat ...
- Centos下的IO监控与分析
近期要在公司内部做个Linux IO方面的培训, 整理下手头的资料给大家分享下 各种IO监视工具在Linux IO 体系结构中的位置 源自 Linux Performance and Tuni ...
- Linux下的IO监控与分析
Linux下的IO监控与分析 近期要在公司内部做个Linux IO方面的培训, 整理下手头的资料给大家分享下 各种IO监视工具在Linux IO 体系结构中的位置 源自 Linux Performan ...
- 【转载】Linux下的IO监控与分析
近期要在公司内部做个Linux IO方面的培训, 整理下手头的资料给大家分享下 各种IO监视工具在Linux IO 体系结构中的位置 源自 Linux Performance and Tuning G ...
- 生产者和消费者模型producer and consumer(单线程下实现高并发)
#1.生产者和消费者模型producer and consumer modelimport timedef producer(): ret = [] for i in range(2): time.s ...
- Linux下的IO监控与分析(转)
各种IO监视工具在Linux IO 体系结构中的位置 源自 Linux Performance and Tuning Guidelines.pdf 1 系统级IO监控 iostat iostat -x ...
- Winform下实现图片切换特效的方法
本文实例讲述了Winform下实现图片切换特效的方法,是应用程序开发中非常实用的一个功能.分享给大家供大家参考之用.具体方法如下: 本实例源自网络,功能较为齐全.丰富!主要功能代码如下: using ...
- Python开发【笔记】:单线程下执行多个定时任务
单线程多定时任务 前言:公司业务需求,实例当中大量需要启动定时器的操作:大家都知道python中的定时器用的是threading.Timer,每当启动一个定时器时,程序内部起了一个线程,定时器触发执行 ...
随机推荐
- POJ旅行商问题——解题报告
旅行商问题 总时间限制: 1000ms 内存限制: 65536kB 描述 某国家有n(1<=n<=10)座城市,给定任意两座城市间距离(不超过1000的非负整数).一个旅行商人希望访问每座 ...
- gunicorn的作用
gunicorn是什么: gunicorn是一种unix上被广泛使用的Python WSGI UNIX HTTP Server WSGI是什么: 先说下 WSGI 的表面意思,Web Server G ...
- [vijos1554&bzoj1411]硬币游戏<快速幂>
题目链接:https://vijos.org/p/1554 http://www.lydsy.com/JudgeOnline/problem.php?id=1411 这题真的淫*QAQ... 一看题还 ...
- memcached-tool 工具
perl memcached-tool server_ip:port stats 输出说明: pid memcache服务器的进程ID uptime 服务器已经运行的秒数 time 服务器当前的uni ...
- B 蒜头君的树
时间限制 : - MS 空间限制 : - KB 评测说明 : 2s,256m 问题描述 蒜头君有一棵有根树,树的每一边都有边权,蒜头君想知道任意两点间最短距离之和为多少. 另外,由于各种原因,蒜 ...
- 码云客户端Gitee使用1上传项目
目前主流的源码仓库有GitHub,这是微软公司的全球最大的代码仓库.里面有来自全世界开发者提供的开源项目或者个人私有项目.它分为个人免费与企业收费两种模式,对于个人学习或者项目开发小组来说个人免费版完 ...
- 3D城市
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- 查找 mysql 配置文件 my.cnf
$ locate my.cnf 看看你的linux上有多少个my.cnf,一般都配置为/etc/my.cnf
- 关于TD信息树自己的体验和建议
自己选择的是17级学长13组的TD消息树,通过对这个软件的使用,感觉整体上还是很好的,他的主要功能就相当于把微信的朋友圈还有qq的好友动态等功能集合到了一起.这个软件整体就相当于一个空间,可以加好友互 ...
- MTK Android ListPreference的用法
首先,我们明确,preference是和数据存储相关的. 其次,它能帮助我们方便的进行数据存储!为什么这个地方一定要强调下方便的这个词呢?原因是,我们可以根本就不使用,我们有另外的N种办法可以实现同样 ...