一、进程池与线程池
无
二、协程
协程可以让我们在单线程下实现并发,是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的。
greenlet模块
from greenlet import greenlet
def eat(name):
print('%s 吃了一口饭' % name)
g2.switch(name) # 切换状态
print('%s 又吃了口饭' % name)
g2.switch()
def tv(name):
print('%s 看了一眼电视' % name)
g1.switch() # 切换状态
print('%s 又看了眼电视' % name)
g1 = greenlet(eat)
g2 = greenlet(tv)
g1.switch('poco')
''' 运行结果
poco 吃了一口饭
poco 看了一眼电视
poco 又吃了口饭
poco 又看了眼电视
'''
gevent模块
并发执行
import time
import gevent
def eat(name):
print('%s 吃了一口饭' % name)
gevent.sleep(1)
print('%s 又吃了口饭' % name)
def tv(name):
print('%s 看了一眼电视' % name)
gevent.sleep(1)
print('%s 又看了眼电视' % name)
res1 = gevent.spawn(eat, 'poco') # 把要执行的函数以及参数放入括号中
res2 = gevent.spawn(tv, 'poco') # 会有返回值
start = time.time() # 统计时间
res1.join()
res2.join()
# gevent.joinall([res1, res2]) # 这一行等同于上面两行代码
print('poco 被打了一顿')
print('执行时间是', time.time()-start) # 统计时间
''' 运行结果
poco 吃了一口饭
poco 看了一眼电视
poco 又吃了口饭
poco 又看了眼电视
poco 被打了一顿
执行时间是 1.0089380741119385
'''
asyncio模块
asyncio模块是Python3.4推出的内置模块,由Python作者主导
import asyncio
# 协程
async def task():
print('1111')
await asyncio.sleep(2)
print('1号协程执行完成')
async def task2():
print('2222')
await asyncio.sleep(2)
print('2号协程执行完成')
loop = asyncio.get_event_loop()
tasks = [task(), task2()]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
猴子补丁
猴子补丁的主要功能便是在不去改变源码的情况下而对功能进行追加和变更。
打个比方说,假如你之前写过一段代码,后来你发现这段代码运行效率不高,于是乎想修改它,但是发现修改的成本有点高,猴子补丁就是来做这件事的,我们可以拿下面代码做个例子
import time
import gevent
# 猴子补丁:把原来的time的IO替换成gevent的IO
from gevent import monkey;monkey.patch_all()
def eat(name):
print('%s 吃了一口饭' % name)
time.sleep(1) # 模拟IO操作
print('%s 又吃了口饭' % name)
def tv(name):
print('%s 看了一眼电视' % name)
time.sleep(1) # 模拟IO操作
print('%s 又看了眼电视' % name)
res1 = gevent.spawn(eat, 'poco') # 把要执行的函数以及参数放入括号中
res2 = gevent.spawn(tv, 'poco') # 会有返回值
start = time.time()
res1.join()
res2.join()
print('poco 被打了一顿')
print('执行时间是', time.time()-start)
''' 运行结果
poco 吃了一口饭
poco 看了一眼电视
poco 又吃了口饭
poco 又看了眼电视
poco 被打了一顿
执行时间是 1.0114164352416992
#不用猴子补丁的执行时间是 2.0248284339904785
'''