【PYTHON模块】:协程与greenlet、gevent
协程:又称为微线程,英文名称Coroutine。
作用:它拥有自己的寄存器上下文和栈,能保留上一次调用时的状态,可以随时暂停程序,随时切换回来。
优点:
•无需线程上下文切换的开销
•无需原子操作锁定及同步的开销
•方便切换控制流,简化编程模型
•高并发+高扩展性+低成本:一个CPU支持上万的协程都不是问题。所以很适合用于高并发处理
缺点:
•无法利用多核资源:协程的本质是个单线程,它不能同时将 单个CPU 的多个核用上,协程需要和进程配合才能运行在多CPU上
•进行阻塞(Blocking)操作(如IO时)会阻塞掉整个程序
使用yield实现协程:
defg(name):print("startingproduct....")whileTrue:baozi=yield#程序暂停等待nextprint("{}iseating{}...".format(name,baozi))defp():conn.__next__()#实例conn启动yieldconn2.__next__()#实例conn2启动yieldi=0whilei<5:i+=1print("product:{}".format(i))conn.send(i)#向yield发送数据,yield恢复,并自动执行nextconn2.send(i)#向yield发送数据,yield恢复,并自动执行nextconn=g("laoda")#创建实例connconn2=g("laoer")#创建实例conn2product=p()#启动函数p
使用greenlet实现协程:不是python自带模块,需要安装
创建协程对象的方法其实有两个参数”greenlet(run=None, parent=None)”。参数”run”就是其要调用的方法,比如上例中的函数test1()和test2();参数”parent”定义了该协程对象的父协程,也就是说,greenlet协程之间是可以有父子关系的。如果不设或设为空,则其父协程就是程序默认的”main”主协程。
fromgreenletimportgreenletdeftest1():print(1)t2.switch()#函数暂停,切换到t2print(2)deftest2():print(3)t1.switch()#函数暂停,切换到t1print(4)t1=greenlet(test1)#test1生成greenlet对象t2=greenlet(test2)#test2生成greenlet对象t1.switch()
使用gevent实现协程:第三方库,需要安装
实现了异步I/O,操作
参数
作用
示例
spawn(func,func_args)
func:加入gevent的函数名
func_args:函数参数
joinall[spawn_list]
spawn_list:spawn方法列表
把创建的协程实例添加到异步列表
等待列表中的所有实例执行完毕
sleep(time)
time:时间(秒)
交出CPU控制权,时间为秒
getcurrent()
获取当前协程内存地址
fromgeventimportgeventimportrandomdefcreat(num):wait_time=random.Randomint(0,num)gevent.sleep(wait_time)print("{}waitdone!".format(gevent.getcrrent()))gevent_list=[]foriinrange(20):gevent_list.append(gevent.spawn(creat,i))gevent.joinall(gevent_list)#Socket并发:(未测试)importgeventimportsocketclassserver(object):def__int__(self,ip,port,*args):self.server_in=socket.socket()self.server_in.bind(ip,port)self.server_in.listen(100)#self.spawn_list=[]defrun(self):client_spawn=[]whileTrue:conn,addr=self.server_in.accept()client_spawn.append(gevent.spawn(handler,conn))gevent.joinall(client_spawn)defhandler(self,conn):whileTrue:recv_data=conn.recv(1024)ifrecv_data='exit':conn.shutdown(socket.SHUT_WR)breakprint("recv:".format(recv_data))conn.send(recv_data.upper())
http://python.jobbole.com/86481/
协程详解
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。