python 协程 gevent
原创
©著作权归作者所有:来自51CTO博客作者jialan75的原创作品,请联系作者获取转载授权,否则将追究法律责任
第三方协程模
- greenlet模块
示例代码: day12/greenlet_0.py
- 安装 : sudo pip3 install greenlet
- 函数
greenlet.greenlet(func)
功能:创建协程对象
参数:协程函数
g.switch()
功能:选择要执行的协程函数
- gevent模块
示例代码: day12/gevent_test.py
示例代码: day12/gevent_server.py
- 安装:sudo pip3 install gevent
- 函数
gevent.spawn(func,argv)
功能: 生成协程对象
参数:func 协程函数
argv 给协程函数传参(不定参)
返回值: 协程对象
gevent.joinall(list,[timeout])
功能: 阻塞等待协程执行完毕
参数:list 协程对象列表
timeout 超时时间
gevent.sleep(sec)
功能: gevent睡眠阻塞
参数:睡眠时间
* gevent协程只有在遇到gevent指定的阻塞行为时才会自动在协程之间进行跳转
如gevent.joinall(),gevent.sleep()带来的阻塞
作用:在gevent协程中,协程只有遇到gevent指定类型的阻塞才能跳转到其他协程,因此,我们希望将普通的IO阻塞行为转换为可以触发gevent协程跳转的阻塞,以提高执行效率。
转换方法:gevent 提供了一个脚本程序monkey,可以修改底层解释IO阻塞的行为,将很多普通阻塞转换为gevent阻塞。
使用方法
【1】 导入monkey
from gevent import monkey
【2】 运行相应的脚本,例如转换socket中所有阻塞
【3】 如果将所有可转换的IO阻塞全部转换则运行all
【4】 注意:脚本运行函数需要在对应模块导入前执行
"""
gevent 协程 模块示例
"""
import gevent
from gevent import monkey
monkey.patch_time()
from time import sleep
# 协程函数
def foo(a, b):
print('Running foo ...', a, b)
sleep(1)
print('Foo again..')
def bar(a, b):
print('Running bar ...', a, b)
print('Bar again..')
# 生成协程对象
f = gevent.spawn(foo, 1, 2)
b = gevent.spawn(bar, 11, 22)
# 4 = 睡眠时间
# gevent.sleep(4)
# 阻塞等待f,b两个协程执行完毕
gevent.joinall([f, b])
"""
gevent server 基于协程的TCP并发
思路:
1.将每个客户端的处理设置设为协程函数
2.让socket模块下的阻塞可以出发协程跳转
"""
import gevent
from gevent import monkey
# 执行脚本,修改socket阻塞
monkey.patch_all()
from socket import *
# 创建tcp套接字
s = socket()
s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
s.bind(('0.0.0.0', 28282))
s.listen(3)
def handle(c):
while True:
data = c.recv(1024).decode()
if not data:
break
print(data)
c.send(b'OK')
# 循环接收客户端连接
while True:
c, addr = s.accept()
print('Connect from', addr)
# 处理具体的客户端请求
gevent.spawn(handle,c)