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切换的更多相关文章

  1. 异步、+回调机制、线程queue、线程Event、协程、单线程实现遇到IO切换

    # from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor # import requests # import o ...

  2. gevent监测单线程下的io进行切换

    from gevent import monkey;monkey.patch_all() import gevent import time def eat(name): print('%s eat ...

  3. Centos下的IO监控与分析

        近期要在公司内部做个Linux IO方面的培训, 整理下手头的资料给大家分享下 各种IO监视工具在Linux IO 体系结构中的位置 源自 Linux Performance and Tuni ...

  4. Linux下的IO监控与分析

    Linux下的IO监控与分析 近期要在公司内部做个Linux IO方面的培训, 整理下手头的资料给大家分享下 各种IO监视工具在Linux IO 体系结构中的位置 源自 Linux Performan ...

  5. 【转载】Linux下的IO监控与分析

    近期要在公司内部做个Linux IO方面的培训, 整理下手头的资料给大家分享下 各种IO监视工具在Linux IO 体系结构中的位置 源自 Linux Performance and Tuning G ...

  6. 生产者和消费者模型producer and consumer(单线程下实现高并发)

    #1.生产者和消费者模型producer and consumer modelimport timedef producer(): ret = [] for i in range(2): time.s ...

  7. Linux下的IO监控与分析(转)

    各种IO监视工具在Linux IO 体系结构中的位置 源自 Linux Performance and Tuning Guidelines.pdf 1 系统级IO监控 iostat iostat -x ...

  8. Winform下实现图片切换特效的方法

    本文实例讲述了Winform下实现图片切换特效的方法,是应用程序开发中非常实用的一个功能.分享给大家供大家参考之用.具体方法如下: 本实例源自网络,功能较为齐全.丰富!主要功能代码如下: using ...

  9. Python开发【笔记】:单线程下执行多个定时任务

    单线程多定时任务 前言:公司业务需求,实例当中大量需要启动定时器的操作:大家都知道python中的定时器用的是threading.Timer,每当启动一个定时器时,程序内部起了一个线程,定时器触发执行 ...

随机推荐

  1. Spring中的设计模式:模板模式

    导读 模板模式在是Spring底层被广泛的应用,比如事务管理器的实现,JDBC模板的实现. 文章首发于作者的微信公众号[码猿技术专栏] 今天就来谈谈「什么是模板模式」.「模板模式的优缺点」.「模板模式 ...

  2. [POJ1190]生日蛋糕<DFS>

    题目链接:http://poj.org/problem?id=1190 题看上去确实很复杂 涉及到半径面积这些,其实看着真的很头疼 但是除去这些就是剪枝优化的dfs算法 #include<cst ...

  3. Pytest系列(4) - fixture的详细使用

    如果你还想从头学起Pytest,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1690628.html 前言 前面一篇讲了setup.te ...

  4. linux中的bash

    一.bash的简介 操作系统都是需要通过shell跟内核来交互的,常见的shell有GUI.KDE.sh.csh.bash.tsh.zsh等. 而linux中最常用的shell就是bash. 二.ba ...

  5. D 楼房重建

    时间限制 : - MS   空间限制 : - KB  评测说明 : 1s,256m 问题描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊 ...

  6. MySQL 同步复制及高可用方案总结

    1.前言 mysql作为应用程序的数据存储服务,要实现mysql数据库的高可用.必然要使用的技术就是数据库的复制,如果主节点出现故障可以手动的切换应用到从节点,这点相信运维同学都是知道,并且可以实现的 ...

  7. PTA数据结构与算法题目集(中文) 7-26

    PTA数据结构与算法题目集(中文)  7-26 7-26 Windows消息队列 (25 分)   消息队列是Windows系统的基础.对于每个进程,系统维护一个消息队列.如果在进程中有特定事件发生, ...

  8. 数据挖掘入门系列教程(八点五)之SVM介绍以及从零开始推导公式

    目录 SVM介绍 线性分类 间隔 最大间隔分类器 拉格朗日乘子法(Lagrange multipliers) 拉格朗日乘子法推导 KKT条件(Karush-Kuhn-Tucker Conditions ...

  9. MyBatis(二):基础CRUD

    本文是按照狂神说的教学视频学习的笔记,强力推荐,教学深入浅出1便就懂!b站搜索狂神说即可 https://space.bilibili.com/95256449?spm_id_from=333.788 ...

  10. 跟面试官侃半小时MySQL事务,说完原子性、一致性、持久性的实现

    提到MySQL的事务,我相信对MySQL有了解的同学都能聊上几句,无论是面试求职,还是日常开发,MySQL的事务都跟我们息息相关. 而事务的ACID(即原子性Atomicity.一致性Consiste ...