1
python3에서 asyncio를 배우기 위해 간단한 RPC 서버와 클라이언트를 작성했지만 asyncio.run_until_complete로 테스트하면 미래가 이미 설정된 후에 차단됩니다. 코드는 다음과 같습니다. 메인 부분을 확인하십시오. 8asyncio.run_until_complete block after future is
를 : 나는이 프로그램을 실행할 때, 제대로미래의 결과처럼 data_received에 결과를 표시, 5 + 을 3 CALC하는 기능 파이썬 3.4.2
import asyncio import struct _req_struct = struct.Struct('<4i') _req_size = _req_struct.size _resp_struct = struct.Struct('<3i') _resp_size = _resp_struct.size class SimpleRPCClient(asyncio.Protocol): _transport = None def __init__(self): self._pendings = {} self.seq_id = 0 self._cached = bytearray() def connection_made(self, transport): """ First event, create ref to transport """ self._transport = transport def send(self, data): """ proxy to transport.write """ self._transport.write(data) def data_received(self, data): c = self._cached c.extend(data) cursor = 0 while len(self._cached) >= (cursor + _resp_size): rid, status, result = _resp_struct.unpack( c[cursor:cursor + _resp_size]) if rid in self._pendings: f = self._pendings.pop(rid) f.set_result(result) print("future result: ", f.result()) def calc(self, oprand, op1, op2): rid = self.seq_id self.seq_id += 1 future = asyncio.Future() self._pendings[rid] = future self.send(_req_struct.pack(rid, oprand, op1, op2)) return future if __name__ == '__main__': loop = asyncio.get_event_loop() host = "127.0.0.1" port = 8087 _tr, client = loop.run_until_complete(loop.create_connection( SimpleRPCClient, host, port)) f = client.calc(1, 3, 5) loop.run_until_complete(f) print("final result: ", f.result())
이다 사용하고 있습니다
그러나 프로그램이 그 이후에 차단되면 최종 결과가 표시되지 않고 미래가 성공적으로 설정되지만 함수가 반환하지 않는 이유는 무엇입니까? 당신이 그것을
import asyncio
import struct
_req_struct = struct.Struct('<4i')
_req_size = _req_struct.size
_resp_struct = struct.Struct('<3i')
_resp_size = _resp_struct.size
class SimpleRPCServer(object):
def build_protocol(self):
return SimpleRPCConnection()
class SimpleRPCConnection(asyncio.Protocol):
_transport = None
def __init__(self):
self._cached = bytearray()
def connection_made(self, transport):
"""
First event, create ref to transport
"""
self._transport = transport
def send(self, data):
"""
proxy to transport.write
"""
self._transport.write(data)
def data_received(self, data):
c = self._cached
c.extend(data)
cursor = 0
while len(self._cached) >= (cursor + _req_size):
seq_id, oprand, op1, op2 = _req_struct.unpack(
c[cursor:cursor + _req_size])
self.respond(seq_id, oprand, op1, op2)
cursor += _req_size
if cursor > len(self._cached):
self._cached.clear()
else:
self._cached[:cursor] = b''
def respond(self, seq_id, oprand, op1, op2):
if oprand == 1:
self.send(_resp_struct.pack(seq_id, 0, op1 + op2))
elif oprand == 2:
self.send(_resp_struct.pack(seq_id, 0, op1 - op2))
elif oprand == 3:
self.send(_resp_struct.pack(seq_id, 0, op1 * op2))
elif oprand == 4:
try:
self.send(_resp_struct.pack(seq_id, 0, op1/op2))
except ZeroDivisionError:
self.send(_resp_struct.pack(seq_id, 1, 0))
else:
self.send(_resp_struct.pack(seq_id, 0xff, 0))
if __name__ == '__main__':
loop = asyncio.get_event_loop()
server = SimpleRPCServer()
loop.run_until_complete(loop.create_server(
server.build_protocol,
"0.0.0.0",
8087))
loop.run_forever()
* 모든 코드를 질문에 넣지 마십시오. 대신에 [* minimal *이지만 완전한 코드 예제를 작성하십시오.] (http://stackoverflow.com/help/mcve) - 질문을 작성할 때 질문에 대답 할 수 있으며 다른 사람들이 문제를 해결하는 데 도움을 줄 수 있습니다. – jfs