我正在尝试使用新的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()
答案 0 :(得分:0)
好的电话Donkopotamus,你应该把它作为答案发布。
我将处理程序包装在try-block中,当它尝试调用conn.recv()时,我得到了异常:[Errno 10038]尝试对不是套接字的操作进行操作。由于工人流程严重死亡,它陷入僵局。使用try-block来捕获错误,我可以继续尽可能多地连接而不会出现任何死锁。
如果我更改代码以使用ThreadPoolExecutor,我不会收到此错误。我已经尝试了几个选项,看起来没有办法正确地将套接字传递给ProcessPoolExecutor中的工作进程。我在互联网上找到了其他的参考资料,但是他们说可以在某些平台上完成,但不能在其他平台上完成。我已经在Windows,Linux和MacOS X上尝试了它,它不适用于任何一个。这似乎是一个重大的限制。
答案 1 :(得分:0)
运行'executor.submit(...)'后,你确定它不是由'conn.close()'引起的吗? 我只是删除该行并尝试使用mac10.12.6和python 3.6.3它运行良好。