-
协程基础
定义:线程,微线程.协程的本质是一个单线程程序,所以协程不能够使用计算机多核 资源.
作用:能够高效的完成并发任务,占用较少的资源,因此协程的并发量较高
原理:利用记录应用层的上下文栈区,实现在运行中进行上下文跳转,达到可以选择性 的运行想要运行的部分,以此提高程序的运行效率
优点:消耗资源少,无需切换开销
无需同步互斥 IO并发性好
缺点:无法利用计算机多核
yield --->协程实现的基本关键字
greenlet
greenlet.greenlet() 生成协程对象
gr.switch() 选择要执行的协程事件
# greenlet0.py
from greenlet import greenlet
def test1():
print(12)
gr2.switch()
print(34)
gr2.switch()
def test2():
print(56)
gr1.switch()
print(78)
# 对象
gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()
gr2.switch()
gevent
1.将协程对象封装为函数
2.生成协程对象
gevent.spawn(func, argv)
功能:生成协程对象
参数:func 协程函数
argv 给协程函数传参
返回值:返回协程对象
3.回收协程
govent.joinall()
功能:回收协程
参数:列表 将要回收的协程放入列表
gevent.sleep(n)
功能:设置协程阻塞,让协程跳转
参数:n 阻塞时间
from gevent import monkey
monkey.patch_all
功能:修改套接字的IO阻塞行为
*必须在socket定义之前使用
import gevent
def foo(a, b):
print('a = %d,b = % d' % (a, b))
# gevent.sleep(2)
print('running foo')
def bar():
print('int bar')
# gevent.sleep(3)
print('running bar')
f = gevent(foo, 1, 2)
b = gevent()
gevent.joinall([f, b]) # 回收协程
# gevent_server.py
import gevent
from gevent import monkey
from socket import *
from time import sleep
monkey.patch_all()
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)