协程:又称为微线程,英文名称协同程序。
作用:它拥有自己的寄存器上下文和栈,能保留上一次调用时的状态,可以随时暂停程序,随时切换回来。
优点:
,,,, ?无需线程上下文切换的开销
,,,, ?无需原子操作锁定及同步的开销
,,,, ?方便切换控制流,简化编程模型
,,,, ?高并发+高扩展性+低成本:一个CPU支持上万的协程都不是问题,所以很适合用于高并发处理
缺点:
,,,, ?无法利用多核资源:协程的本质是个单线程,它不能同时将单个CPU的多个核用上,协程需要和进程配合才能运行在多CPU上
,,,, ?进行阻塞(阻塞)操作(如IO时)会阻塞掉整个程序
,
- <李>
李>
def g(名称): ,打印(“starting  product ....“) ,while 真正的: 包子才能=,油品收率,#,程序暂停等待下一个 打印才能(“{},is eating {}…“.format(名称、包子)) def p (): ,conn.__next__(),, #,实例康涅狄格州启动屈服 ,conn2.__next__(), #,实例conn2启动屈服 ,小姐:=0 ,while i<5: 小姐:才能+=1 打印才能(“产品:{}“.format(我)),, conn.send才能(i), #,向产量发送数据,收益率恢复,并自动执行 conn2.send才能(i), #,向产量发送数据,收益率恢复,并自动执行 时间=conn g (“laoda"),, #,创建实例 时间=conn2 g (“laoer"),,,,,, #,创建实例conn2 product =, p(),,, #,启动函数p
,
,
- <李>
李>
,,,,,,,,创建协程对象的方法其实有两个参数“一种绿色小鸟(=没有运行,父母=None)”。参数就“跑”是其要调用的方法,比如上例中的函数test1和test2()();参数“父”定义了该协程对象的父协程,也就是说,一种绿色小鸟协程之间是可以有父子关系的。如果不设或设为空,则其父协程就是程序默认的“主要”主协程。
得到greenlet import 一种绿色小鸟 def test1 (): ,,,印刷(1) ,,,t2.switch(),,,, #,函数暂停,切换到t2 ,,,(2)打印 def test2 (): ,,,印刷(3) ,,,t1.switch(),,,, #,函数暂停,切换到t1 ,,,(4)打印 ,, t1=一种绿色小鸟(test1),,,, #, test1生成一种绿色小鸟对象 t2=一种绿色小鸟(test2),,,, #, test2生成一种绿色小鸟对象 t1.switch ()
- <李>
使用gevent实现协程:第三方库,需要安装
李>实现了异步I/O,操作
参数
作用
示例
产卵(func func_args)
func:加入gevent的函数名
func_args:函数参数
joinall [spawn_list]
spawn_list:产卵方法列表
把创建的协程实例添加到异步列表
等待列表中的所有实例执行完毕
睡眠(时间)
时间:时间(秒)
交出CPU控制权,时间为秒
getcurrent ()
获取当前协程内存地址
得到gevent import gevent import 随机 def 创造(num):=,,wait_time  random.Randomint (0, num) ,gevent.sleep (wait_time) ,打印(“{},wait 完成了!“.format (gevent.getcrrent ())) , 时间=gevent_list [] for 小姐:拷贝范围(20): ,gevent_list.append (gevent.spawn(创造,,我)) gevent.joinall (gevent_list) #套接字并发:(未测试) import gevent import 套接字 class 服务器(对象): ,def __int__(自我、ip、端口、* args): 时间=self.server_in 才能;socket.socket () self.server_in.bind才能(ip、端口) self.server_in.listen才能(100) #,才能self.spawn_list =, [] ,, ,def 运行(自我): 时间=client_spawn 才能;[] while 才能正确的: ,,康涅狄格州,addr =, self.server_in.accept () ,,client_spawn.append (gevent.spawn(处理程序,康涅狄格州)) gevent.joinall才能(client_spawn) ,, ,, 康涅狄格州,def 处理程序(自我): while 才能正确的: ,,recv_data =, conn.recv (1024) ,,if recv_data =, & # 39;退出# 39;: ,,,conn.shutdown (socket.SHUT_WR) ,才能打破 ,才能打印(“recv:“.format (recv_data)) ,,conn.send (recv_data.upper ())
,