2017-10-17 11 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ソケットの前にサブプロセスを開始する必要があります。そうしないと、すべての子プロセスに共有されます。 – georgexsh

答えて

2

close参照を保持していない他のプロセスがない限り本当に接近していない接続を行いますが、shutdownは、すべてのプロセスに影響します。 の前にclient_socket.shutdown(socket.SHUT_WR)と呼ぶことができます。


更新:closeが完全に閉じていない接続を行い

理由はManager()で起動したプロセスの参照を保持しているがあります。代わりにQueueを使用すると、closeが期待どおりに機能します。

+0

[docsの関連セクション](https://docs.python.org/3.6/library/socket.html#socket.socket.close)へのリンクを追加すると便利です。 – skrrgwasme

関連する問題