Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3 concurrent.futures套接字服务器使用ThreadPoolExecutor,但不使用ProcessPoolExecutor_Python_Sockets_Python 3.x_Python 3.2_Concurrent.futures - Fatal编程技术网

Python 3 concurrent.futures套接字服务器使用ThreadPoolExecutor,但不使用ProcessPoolExecutor

Python 3 concurrent.futures套接字服务器使用ThreadPoolExecutor,但不使用ProcessPoolExecutor,python,sockets,python-3.x,python-3.2,concurrent.futures,Python,Sockets,Python 3.x,Python 3.2,Concurrent.futures,我正在尝试使用新的concurrent.futures类创建一个简单的套接字服务器。我可以让它与ThreadPoolExecutor一起正常工作,但当我使用ProcessPoolExecutor时它只是挂起,我不明白为什么。考虑到这种情况,我认为这可能与试图将无法pickle的内容传递给子进程有关,但我不这么认为。下面是我的代码的简化版本。如果您有任何建议,我将不胜感激 import concurrent.futures import socket, os HOST = '' PORT = 9

我正在尝试使用新的concurrent.futures类创建一个简单的套接字服务器。我可以让它与ThreadPoolExecutor一起正常工作,但当我使用ProcessPoolExecutor时它只是挂起,我不明白为什么。考虑到这种情况,我认为这可能与试图将无法pickle的内容传递给子进程有关,但我不这么认为。下面是我的代码的简化版本。如果您有任何建议,我将不胜感激

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()

打电话给Donkopotamus很好,你应该把这个作为答案

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


如果将代码更改为使用ThreadPoolExecutor,则不会出现此错误。我尝试了几个选项,但似乎无法在ProcessPoolExecutor中将套接字正确地传递给工作进程。我在互联网上找到了其他关于这方面的参考资料,但他们说这可以在某些平台上完成,但在其他平台上则不行。我曾在Windows、Linux和MacOS X上试用过,但都不起作用。这似乎是一个很大的限制。

运行“executor.submit(…)”后,是否确定这不是由“conn.close()”引起的?
我只是删除了这行代码,并在mac10.12.6和python 3.6.3上进行了尝试。它工作得很好。

如果有帮助,在python 3.2中,ProcessPoolExecutor在工作人员严重死亡时会死锁(例如没有退出值0)。Good call@Donkopotamus,您应该将其作为答案而不是评论发布。