协程
- 协程也叫纤程,微线程。协程的本质是一个单线程程序,所以协程不能够使用计算机多核资源。
- 能够高效的完成并发任务,占用较少的资源,因此协程的并发量较高。
原理
通过记录应用层的上下文栈区,实现在运行中进行上下文跳转,达到可以选择性地运行想要运行的部分,以此提高程序的运行效率。
优缺点
- 优点
- 消耗资源少
- 无需切换开销
- 无需同步互斥
- IO并发性好
- 缺点
- 无法利用计算机多核
greenlet
import greenlet
# 生成协程对象
greenlet.greenlet()
# 选择要执行的协程事件
gr.switch()
示例
from greenlet import greenlet
def fun1():
print(12)
gr2.switch()
print(34)
gr2.switch()
def fun2():
print(56)
gr1.switch()
print(78)
gr1.switch()
gr1 = greenlet(fun1)
gr2 = greenlet(fun2)
gr1.switch()
gevent
- 将协程事件封装为函数
- 生成协程对象
gevent.spawn(func,argv)
# 功能:生成协程对象
# 参数:func 协程函数
# argv 给协程函数传参
# 返回值:返回协程对象
- 回收协程
gevent.joinall()
# 功能:回收协程,触发协程的执行
# 参数:列表,将要回收的协程放入列表
gevent.sleep(n)
# 功能:设置协程阻塞,让协程跳转
# 参数:n 阻塞时间
示例
import gevent
from time import sleep
def foo(a,b):
print('a = %d,b = %d' % (a,b))
print('foo first')
# 让协程跳转
gevent.sleep(3)
print('foo again')
def bar():
print('bar first')
# 让协程跳转
gevent.sleep(3)
print('bar again')
f = gevent.spawn(foo,1,2)
g = gevent.spawn(bar)
print('------------')
# 触发协程的执行
gevent.joinall([f,g])
print('++++++++++++')
协程实现并发
# from gevent import monkey
# monkey.patch_all()
# 功能:修改套接字的IO阻塞行为
# 必须在socket导入之前使用
import gevent
from gevent import monkey
monkey.patch_all()
from socket import *
from time import ctime
def server(port):
s = socket()
s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
s.bind(('0.0.0.0',port))
s.listen(3)
while True:
c,addr = s.accept()
print("Connect from ",addr)
# handler(c) #循环服务器
gevent.spawn(handler,c) #协程服务器
def handler(c):
while True:
data = c.recv(1024)
if not data:
break
print(data.decode())
c.send(ctime().encode())
c.close()
if __name__ == "__main__":
server(8888)
网友评论