저는 python3 + asyncio를 통해 다중 프로세스 서버 프로그램을 작성하려고합니다. 그리고 AbstractEventLoop.create_server에 'reuse_port'라는 매개 변수가 있다는 것을 발견했습니다.python3 asyncio reuse_port를 통해 올바른 다중 프로세스 서버 프로그램을 작성하는 방법?
일부 코드를 작성 했으므로 다중 프로세스를 사용하여 일부 프로세스를 작성하고 각 프로세스는 asyncio 이벤트 루프를 작성하며 이러한 모든 프로세스는 동일한 포트에서 수신 대기합니다.
이 프로세스가 함께 작동하여 요청에 응답 할 수 있다고 생각했지만이 서버 프로그램을 테스트 할 때 단 하나의 프로세스 만 내 요청에 항상 응답합니다.
다른 프로세스가 요청에 응답하지 않는 이유는 무엇입니까? 내 코드에 버그가 있습니까?
OSX10.11 + PYTHON3.5.2
서버 :
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import os
import sys
import multiprocessing
import asyncio
import socket
tcp_listen_port = 44330
class Listener:
def __init__(self, protocol, listen_port, listen_host='localhost'):
self._protocol = protocol
self._listen_port = listen_port
self._listen_host = listen_host
self._loop = None
self._server = None
self._pid = os.getpid()
def run(self):
asyncio.set_event_loop(asyncio.new_event_loop())
self._loop = asyncio.get_event_loop()
coro = self._loop.create_server(
self._protocol,
host=self._listen_host,
port=self._listen_port,
family=socket.AF_INET,
reuse_port=True
)
self._server = self._loop.run_until_complete(coro)
print('Listener Server on {}, pid {}'.format(
self._server.sockets[0].getsockname(),
self._pid
))
self._loop.run_forever()
def close(self):
self._server.close()
self._loop.run_until_complete(self._server.wait_closed())
self._loop.close()
class ProtocolEcho(asyncio.Protocol):
def connection_made(self, transport):
self.transport = transport
def data_received(self, data):
data = 'hello python asyncio from pid {}\r\n\r\n'.format(os.getpid()).encode()
self.transport.write(data)
self.transport.close()
def create_tcp_srv(listen_port):
listener = Listener(ProtocolEcho, listen_port)
try:
listener.run()
except KeyboardInterrupt:
listener.close()
def main():
cpu_count = multiprocessing.cpu_count()
srvproclist = list()
for i in range(cpu_count):
p = multiprocessing.Process(
target=create_tcp_srv,
args=(tcp_listen_port,)
)
srvproclist.append(p)
for proc in srvproclist:
proc.start()
for proc in srvproclist:
proc.join()
if __name__ == '__main__':
main()
클라이언트
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import os
import asyncio
import multiprocessing
async def req():
connect = asyncio.open_connection('localhost', 44330)
reader, writer = await connect
writer.write('hello'.encode('utf-8'))
await writer.drain()
while True:
line = await reader.readline()
if line == b'\r\n':
break
print('proc {} recv {}'.format(os.getpid(), line.decode()))
writer.close()
def begin_test():
asyncio.set_event_loop(asyncio.new_event_loop())
loop = asyncio.get_event_loop()
tasks = [req() for i in range(10)]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
plist = list()
for i in range(4):
p = multiprocessing.Process(
target=begin_test
)
plist.append(p)
for proc in plist:
proc.start()
for proc in plist:
proc.join()
이런 클라이언트 출력 :
proc 72319 recv hello python asyncio from pid 72310
proc 72318 recv hello python asyncio from pid 72310
proc 72319 recv hello python asyncio from pid 72310
proc 72320 recv hello python asyncio from pid 72310
proc 72321 recv hello python asyncio from pid 72310
proc 72319 recv hello python asyncio from pid 72310
proc 72318 recv hello python asyncio from pid 72310
proc 72320 recv hello python asyncio from pid 72310
proc 72321 recv hello python asyncio from pid 72310
proc 72318 recv hello python asyncio from pid 72310
proc 72320 recv hello python asyncio from pid 72310
proc 72321 recv hello python asyncio from pid 72310
마지막 숫자 '72310'은 내 요청에 응답 한 서버 프로세스 PID이며 하나의 프로세스 만 작동하고 있다고 생각합니다. 그러나 왜 ...