2011-09-25 34 views
0

我想创建一个简单的套接字服务器使用新的concurrent.futures类。我可以使用ThreadPoolExecutor正常工作,但是当我使用ProcessPoolExecutor时它会挂起,我不明白为什么。考虑到这种情况,我认为这可能与尝试将某些事情传递给儿童流程不可兼得,但我并非如此。下面是我的代码的简化版本。我将不胜感激任何建议。Python 3 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() 
+1

如果有帮助,在Python 3.2中ProcessPoolExecutor会死锁,如果一个工人死亡严重(例如没有退出值0)。 – donkopotamus

+0

良好的电话@Donkopotamus,你应该发布这个答案而不是评论。 – ThatAintWorking

回答

0

好电话Donkopotamus,你应该已经发布,作为答案。

我把这个处理程序放在一个try-block中,当它试图调用conn.recv()时,我得到了这个异常:[Errno 10038]在一个不是socket的东西上尝试了一个操作。由于工人进程严重死亡,它陷入僵局。使用try-block捕获错误,我可以继续尽可能多地连接,而不会发生任何死锁。

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

0

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