python中协程的使用

it2022-05-05  103

协程基础 定义: 协程,微线程。协程的本质是一个单线程程序,所以协程不能使用计算机多核资源。 作用: 能够高效的完成并发任务,占用较少的资源。 因此协程的并发量较高 原理: 通过记录应用层的上下文栈区,实现在运行中进行上下文跳转,达到可以选择性地运行想要运行的部分,以此提高程序的运行效率。 优点: 消耗资源少 无需切换开销 无需同步互斥 IO并发性好 缺点: 无法利用计算机多核 python中的协程使用 yield --> 协程实现的基本关键字 基于yield封装实现的第三方库: greelet greenlet.greenlet(func) 生成协程对象 gr.switch() 选择要执行的协程对象并记录执行位置 gevent : 基于greenlet 1.将协程事件封装为函数 2. 生成协程对象 gevent.spawn(func,argv) 功能: 生成协程对象 参数: func 协程函数 argv 给协程函数传参 3. 回收协程 gevent.joinall(list) 功能: 回收协程 参数: 列表 将要回收的协程放入列表 4. gevent.sleep(n) 功能: 设置协程阻塞,让协程跳转 参数: n 阻塞时间 from gevent import monkey monkey.patch_all() 功能:修改套接字的IO阻塞行为 * 必须在socket导入之前使用 greenlet测试 #测试greenlet模块函数 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() # 启动协程1 #打印结果: 12 56 34 78 gevent测试 #gevent模块测试 import gevent def foo(a,b): print('a = {}, b = {}'.format(a,b)) gevent.sleep(2) print('Runing foo again') def bar(): print('Runing in bar') gevent.sleep(3) print('Runing bar again') #生成协程 f = gevent.spawn(foo,1,2) g = gevent.spawn(bar) print('==============') gevent.joinall([f,g]) print('%%%%%%%%%%%%%%') gevent.monkey.patch_all()处理后的高并发协程 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 {}'.format(addr)) #handler(c) 循环模型服务器一次只能处理一个请求 gevent.spawn(handler,c,addr) # 协程高并发处理请求 def handler(c,addr): #处理客户端请求 while True: data = c.recv(1024) if not data: print('连接断开:{}'.format(addr)) break print(data.decode()) c.send(ctime().encode()) c.close() if __name__ == '__main__': port = 8888 s = server(port)

最新回复(0)