2017-10-17 104 views
0

我有一个主进程acepting套接字连接的服务器,并将它们放入队列堆栈中,另一个进程监视此堆栈并将其应用于处理连接的池进程。除了一件事情,所有的工作都很好:使用多处理来处理套接字

  • 最后一次连接allways at stuck直到出现另一个连接,它看起来像上次连接无法关闭,但为什么?
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'语句的好用例。即使你不能把插座闭合的东西弄平,你也不应该去做任何事情。 – skrrgwasme

+0

您应该在init父节点侦听套接字之前启动子进程,否则它将共享给所有子进程。 – georgexsh

回答

2

close不真的,除非没有其他进程持有的引用,但shutdown会影响到所有进程密切相关。您可以在client_socket.close()之前致电client_socket.shutdown(socket.SHUT_WR)


更新:

的原因close不完全关闭连接有由Manager()开始是抱着一个参考的过程。如果使用Queue,则会使close按预期工作。

+0

添加一个链接到[文档的相关部分](https://docs.python.org/3.6/library/socket.html#socket.socket.close)会很有帮助。 – skrrgwasme