使用多处理来处理套接字

时间:2017-10-17 05:14:12

标签: python python-multiprocessing

我有一个带有主进程acepting套接字连接的服务器,并将它们放入Queue堆栈,另一个进程监视此堆栈并将其应用于处理连接的池进程。一切都很好,除了一件事:

  • 最后的连接总是卡住,直到出现另一个连接,它看起来像最后一个连接无法关闭,但为什么?
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()

1 个答案:

答案 0 :(得分:2)

close并非真正关闭连接,除非没有其他进程持有引用,但shutdown会影响所有进程。您可以在client_socket.shutdown(socket.SHUT_WR)之前致电client_socket.close()

更新

close没有完全关闭连接的原因是Manager()启动的进程持有引用。使用Queue代替close可以按预期工作。