第三方协程模

  1. greenlet模块

示例代码: day12/greenlet_0.py

  • 安装 : sudo pip3 install greenlet
  • 函数
greenlet.greenlet(func)
功能:创建协程对象
参数:协程函数

g.switch()
功能:选择要执行的协程函数
  1. 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()带来的阻塞
  • monkey脚本

作用:在gevent协程中,协程只有遇到gevent指定类型的阻塞才能跳转到其他协程,因此,我们希望将普通的IO阻塞行为转换为可以触发gevent协程跳转的阻塞,以提高执行效率。

转换方法:gevent 提供了一个脚本程序monkey,可以修改底层解释IO阻塞的行为,将很多普通阻塞转换为gevent阻塞。

使用方法

【1】 导入monkey

from gevent  import monkey

【2】 运行相应的脚本,例如转换socket中所有阻塞

monkey.patch_socket()

【3】 如果将所有可转换的IO阻塞全部转换则运行all

monkey.patch_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)