Python 3 concurrent.futures Socket 服务器在 ThreadPoolExecutor 中可用,但在 ProcessPoolExecutor 中不可用
我正在尝试使用新的 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()
2 个回答
0
你确定不是因为在运行 'executor.submit(...)' 之后调用了 'conn.close()' 吗?我只是把那一行去掉,然后在 mac10.12.6 和 python 3.6.3 上试了一下,结果很好。
0
说得好,Donkopotamus,你应该把这个当作答案发出来。
我把处理程序放在了一个尝试块里,当它试图调用 conn.recv() 时,我遇到了一个错误:[Errno 10038] 尝试在一个不是套接字的东西上进行操作。由于工作进程死掉得很惨,它出现了死锁。现在有了这个尝试块来捕捉错误,我可以继续连接,想连接多少就连接多少,而不会再出现死锁的问题。
如果我把代码改成使用 ThreadPoolExecutor,我就不会遇到这个错误。我尝试了几种方法,发现用 ProcessPoolExecutor 传递套接字给工作进程似乎没有正确的方法。我在网上找到了其他相关的信息,他们说在某些平台上可以做到,但在其他平台上不行。我在 Windows、Linux 和 MacOS X 上都试过了,结果在这些系统上都不行。这似乎是一个很大的限制。