2

我正在尝试使用新的 concurrent.futures 类创建一个简单的套接字服务器。我可以让它与 ThreadPoolExecutor 一起正常工作,但是当我使用 ProcessPoolExecutor 时它只是挂起,我不明白为什么。鉴于这种情况,我认为这可能与试图将某些不能腌制的子进程传递给子进程有关,但我不这么认为。我的代码的简化版本如下。我会很感激任何建议。

import concurrent.futures
import socket, os

HOST = ''
PORT = 9001

def request_handler(conn, addr):
    pid = os.getpid()
    print('PID', pid, 'handling connection from', addr)
    while True:
        data = conn.recv(1024)
        if not data:
            print('PID', pid, 'end connection')
            break
        print('PID', pid, 'received:', bytes.decode(data))
        conn.send(data)
    conn.close()

def main():
    with concurrent.futures.ProcessPoolExecutor(max_workers=4) as executor:
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
            sock.bind((HOST, PORT))
            sock.listen(10)
            print("Server listening on port", PORT)
            while True:
                conn, addr = sock.accept()
                executor.submit(request_handler, conn, addr)
                conn.close()
            print("Server shutting down")


if __name__ == '__main__':
    main()
4

2 回答 2

0

好电话 Donkopotamus,您应该将其发布为答案。

我将处理程序包装在一个 try 块中,当它尝试调用 conn.recv() 时出现异常:[Errno 10038] 尝试对非套接字的操作进行操作。由于工作进程严重死亡,因此陷入僵局。使用 try-block 捕获错误,我可以继续尽可能多地连接,而不会出现任何死锁。

如果我将代码更改为使用 ThreadPoolExecutor,我不会收到此错误。我尝试了几个选项,看起来没有办法正确地将套接字传递给 ProcessPoolExecutor 中的工作进程。我在互联网上找到了其他对此的参考,但他们说可以在某些平台上完成,但不能在其他平台上完成。我已经在 Windows、Linux 和 MacOS X 上尝试过它,但它在其中任何一个上都不起作用。这似乎是一个重大限制。

于 2011-09-26T17:49:04.403 回答
0

你确定它不是在你运行'executor.submit(...)'之后由'conn.close()'引起的吗?我只是删除该行并尝试在 mac10.12.6 和 python 3.6.3 上运行良好。

于 2017-12-16T15:53:38.073 回答