2014-03-05 83 views
4

在异步(线程)SocketServer的示例中,启动了一个服务器线程(称为server_thread),以便为每个请求启动新线程。由于捕捉KeyboardInterrupts的一些问题,我开始寻找类似的代码,并发现没有明显的区别,当不使用服务器线程,但ctrl-c实际上工作。SocketServer ThreadingMixIn目的server_thread

即使我的代码中使用server_thread工作时,我非常想知道

1)为什么没有一个简单的“尝试”赶上一个KeyboardInterrupt工作?

2)来自示例的server_thread服务有什么好处 - 与我的更简单的示例相反?

从Python的SocketServer例如,在尝试捕获一个KeyboardInterrupt不起作用:

if __name__ == "__main__": 
    server = ThreadedTCPServer(serverAddr, SomeCode) 
<snip> 
    # Start a thread with the server -- that thread will then start one 
    # more thread for each request 
    server_thread = threading.Thread(target=server.serve_forever) 
    server_thread.start() 

我简单的例子,CTRL-C的作品。

if __name__ == "__main__": 
    server = ThreadedTCPServer(serverAddr, SomeCode) 
    try: 
     server.serve_forever() 
     print "ctrl-c to exit" 
    except KeyboardInterrupt: 
     print "interrupt received, exiting" 
     server.shutdown() 

回答

3

1)这是一个普遍的问题。当你做CTRL + C时,一个信号被发送到进程。在这个过程中,主线程捕获信号,并且(如果处理不当)主线程会中断。但是这个信号并不会杀死其他线程。只要有非守护进程线程运行,Python就不会退出(因为这不会安全)。如果你知道你在做什么,你可以补充一点:

server_thread = threading.Thread(target=server.serve_forever) 
server_thread.daemon = True 
server_thread.start() 

,它应该工作现在(假设你server_thread.start()喜欢等待之后做一些事情 - 否则Python将只需要退出,也不会等待守护线程)。但是请记住,在某些重要操作中,您可能会终止服务器。为了避免这种情况,你应该实现某种优雅杀:

import signal 

if __name__ == "__main__": 
    server = ThreadedTCPServer(serverAddr, SomeCode) 

    # some code 
    server_thread = threading.Thread(target=server.serve_forever) 
    server_thread.start() 
    # some code 

    try: 
     signal.pause() # wait for a signal, perhaps in a loop? 
    except: 
     server.shutdown() # graceful quit 

2)这只是开始于一个单独的线程的服务器。也许这个想法是你可以在此期间进行其他操作?如果您只想运行服务器,则无需这样做。

此外,原因可能是我上面所说的那个:优雅退出。如果你只是打断服务器,它会死的,也许在一些重要的操作过程中。

+0

您可以在'serve_forever()'中打断ThreadedTCPServer。它没有什么重要的。重要的任务可能在您可能要等待的处理程序线程中。 – User

1

在服务器线程示例中,您将启动一个提供内容的新线程。 此线程不像deamon(deamon = False)。这意味着程序在server_forever()完成之前不会退出。 所以主线程什么都不做,程序等待非deamon线程关闭。

  1. 我看到的唯一区别是这个新线程不是主线程,因此不处理KeyboardInterrupt或主线程所做的其他事情。
  2. 如果要将GUI与服务器集成,这可能会很有用。 GUI可以并行运行。
+0

“打印”ctrl-c退出“'仍然执行,所以我希望尝试工作。如果它只停留在server_thread中,那么打印不应该起作用,或者我错了吗? – user135361

+0

对不起,您打算打印哪张?你能解释更多吗? – User