2017-10-17 7 views
0

메인 프로세스가 소켓 연결을 받아들이는 서버를 가지고 큐 스택에 넣고이 스택을 모니터링하는 다른 프로세스를 연결을 처리하는 풀 프로세스에 적용합니다. 한 가지를 제외하고 모두 정상적으로 작동합니다.멀티 프로세싱을 사용하여 소켓을 처리하기

  • 마지막 연결은 항상 표시됩니다.
from multiprocessing import Queue, Process, Pool, Manager 
import datetime 
import socket 

def get_date(): 
    return datetime.datetime.now().strftime('%H:%M:%S') 


class Server: 
    def __init__(self, host, port): 
     self.server_address = host, port 
     self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 


    def run(self): 
     self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
     self.server_socket.bind(self.server_address) 
     self.server_socket.listen(1) 

     print('listen at: %s:%s' % self.server_address) 

     q = Manager().Queue() 
     Process(target=self.handle_request, args=(q,)).start() 

     while True: 
      client_socket, adress = self.server_socket.accept() 
      print('\n[%s] request from: %s:%s' % (get_date(), *adress)) 
      q.put(client_socket) 
      client_socket.close() 
      del client_socket # client_socket.close() not working 


    def help(self, client_socket): 
     data = client_socket.recv(512) 
     client_socket.send(data) 
     client_socket.close() 
     print(data[:50]) 

    def handle_request(self, q): 
     with Pool(processes=2) as pool: 
      while True: 
       pool.apply_async(self.help, (q.get(),)) 


Server('localhost', 8000).run() 
+0

이것은 'del' 문을 사용하는 좋은 사례가 아닙니다. 소켓을 닫을 수없는 경우에도 실제로는 "del"해서는 안됩니다. – skrrgwasme

+0

init parent listen 소켓보다 먼저 subprocess를 시작해야합니다. 그렇지 않으면 모든 자식 프로세스에 공유됩니다. – georgexsh

답변

2

close은하지 정말 다른 프로세스에 대한 참조를 유지하지 않지만 shutdown은 모든 프로세스에 영향을 미칠 것입니다하지 않는 밀접한 관련을 수행합니다. 전에 client_socket.shutdown(socket.SHUT_WR)으로 전화 할 수 있습니다.


업데이트 :

이유 close이 아닌 완전히 밀접한 관계가 참조를 들고 Manager()에 의해 시작 프로세스가됩니다 않습니다. 대신 Queue을 사용하면 close이 예상대로 작동합니다.

+0

[관련 문서 섹션] (https://docs.python.org/3.6/library/socket.html#socket.socket.close) 링크를 추가하면 도움이됩니다. – skrrgwasme