python 使用事件对象asyncio.Event来同步协程的操作
事件对象asyncio.Event是基于threading.Event来实现的。
事件可以一个信号触发多个协程同步工作,
例子如下:
importasyncio importfunctools defset_event(event): print('settingeventincallback') event.set() asyncdefcoro1(event): print('coro1waitingforevent') awaitevent.wait() print('coro1triggered') asyncdefcoro2(event): print('coro2waitingforevent') awaitevent.wait() print('coro2triggered') asyncdefmain(loop): #Createasharedevent event=asyncio.Event() print('eventstartstate:{}'.format(event.is_set())) loop.call_later( 0.1,functools.partial(set_event,event) ) awaitasyncio.wait([coro1(event),coro2(event)]) print('eventendstate:{}'.format(event.is_set())) event_loop=asyncio.get_event_loop() try: event_loop.run_until_complete(main(event_loop)) finally: event_loop.close()
输出如下:
eventstartstate:False coro2waitingforevent coro1waitingforevent settingeventincallback coro2triggered coro1triggered eventendstate:True
补充知识:python里使用协程来创建echo客户端
在这个例子里使用asyncio.Protocol来创建一个echo客户端,先导入库asyncio和logging。
接着定义发送的消息MESSAGES。
创建连接服务器的地址SERVER_ADDRESS,接着创建EchoClient类,它是继承asyncio.Protocol。
在这个类的构造函数里,接收两个参数messages和future,
messages是指定要发送的消息数据,future是用来通知socket接收数据完成或者服务器关闭socket的事件通知,以便事件循环知道这个协程已经完成了,就可以退出整个程序。
connection_made函数是当socket连接到服务器时调用,它就立即发送数据给服务器,数据发送完成之后发送了eof标记。
服务器收到数据和标志都回复客户端,客户端data_received函数接收数据,eof_received函数接收结束标记。
connection_lost函数收到服务器断开连接。
这行代码:
client_completed=asyncio.Future()
创建一个协程完成的触发事件。
由于event_loop.create_connection函数只能接收一个参数,需要使用functools.partial来进行多个参数包装成一个参数。
后面通过事件循环来运行协程。
importasyncio importfunctools importlogging importsys MESSAGES=[ b'Thisisthemessage.', b'Itwillbesent', b'inparts.', ] SERVER_ADDRESS=('localhost',10000) classEchoClient(asyncio.Protocol): def__init__(self,messages,future): super().__init__() self.messages=messages self.log=logging.getLogger('EchoClient') self.f=future defconnection_made(self,transport): self.transport=transport self.address=transport.get_extra_info('peername') self.log.debug( 'connectingto{}port{}'.format(*self.address) ) #Thiscouldbetransport.writelines()exceptthat #wouldmakeithardertoshoweachpartofthemessage #beingsent. formsginself.messages: transport.write(msg) self.log.debug('sending{!r}'.format(msg)) iftransport.can_write_eof(): transport.write_eof() defdata_received(self,data): self.log.debug('received{!r}'.format(data)) defeof_received(self): self.log.debug('receivedEOF') self.transport.close() ifnotself.f.done(): self.f.set_result(True) defconnection_lost(self,exc): self.log.debug('serverclosedconnection') self.transport.close() ifnotself.f.done(): self.f.set_result(True) super().connection_lost(exc) logging.basicConfig( level=logging.DEBUG, format='%(name)s:%(message)s', stream=sys.stderr, ) log=logging.getLogger('main') event_loop=asyncio.get_event_loop() client_completed=asyncio.Future() client_factory=functools.partial( EchoClient, messages=MESSAGES, future=client_completed, ) factory_coroutine=event_loop.create_connection( client_factory, *SERVER_ADDRESS, ) log.debug('waitingforclienttocomplete') try: event_loop.run_until_complete(factory_coroutine) event_loop.run_until_complete(client_completed) finally: log.debug('closingeventloop') event_loop.close()
以上这篇python使用事件对象asyncio.Event来同步协程的操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。