2016-07-28 32 views
1

我想在多個線程中運行多個IOLoop,我想知道IOLoop如何實際工作。龍捲風在多線程中的多個IOLoop

class WebThread(threading.Thread): 
    def __init__(self): 
     threading.Thread.__init__(self, name='WebThread') 

    def run(self): 
     curdir = os.path.dirname(os.path.realpath(__file__)) 

     application = Application() #Very simple tornado.web.Application 
     http_server_api = tornado.httpserver.HTTPServer(application) 
     http_server_api.listen(8888) 

     logging.info('Starting application') 

     #tornado.ioloop.IOLoop.instance() is singleton, not for thread, right? 

     ioloop = tornado.ioloop.IOLoop() 
     ioloop.make_current() 
     ioloop.start() 

按照醫生,我不能用IOLoop.instance(),因爲它是一個單身,我在一個線程工作。所以我創建了我自己的IOLoop。但是這段代碼在端口8888上偵聽,但不能渲染任何網頁。我想知道是否有任何遺漏,或者我需要以某種方式將http_server綁定到IOLoop?

此外,我發現刪除最後3行並替換爲tornado.ioloop.IOLoop.instance().start完美適用於單線程。但是單身人士和自己創造的IOLoop有什麼區別?

我是新來的龍捲風,歡迎任何答案。

回答

2

一般而言,在構建異步對象時,應該使用IOLoop.current作爲默認值,並且當您意圖從不同的主通道傳遞到主線程時使用IOLoop.instance。

IOLoop.current沒有PARAMS回報已經ioloop線程的創建或調用IOLoop.instance()。而HTTPServer(實際上在TCPServer中)使用IOLoop.current與ioloop進行交互,所以你應該改變的唯一的事情就是在HTTPServer之前創建ioloop。

class WebThread(threading.Thread): 
    def __init__(self): 
     threading.Thread.__init__(self, name='WebThread') 

    def run(self): 
     curdir = os.path.dirname(os.path.realpath(__file__)) 

     ioloop = tornado.ioloop.IOLoop() 

     application = Application() #Very simple tornado.web.Application 
     http_server_api = tornado.httpserver.HTTPServer(application) 
     http_server_api.listen(8888) 

     logging.info('Starting application') 

     ioloop.start() 

而且我已經刪除IOLoop.make_current,因爲它是多餘的 - IOLoop()設置自爲的電流。


上面的代碼將工作,但只有一個線程,因爲默認情況下不啓用reuse_port。您將結束:

OSError: [Errno 98] Address already in use 

您可以

http_server_api.bind(port=8888, reuse_port=True) 
    http_server_api.start() 

,而不是http_server_api.listen(8888)

+0

這是真棒回答,感謝啓用這個功能。我不知道http_server與當前的IOLoop進行交互。非常感謝你的解釋。 –