2014-03-05 85 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