2016-07-28 10 views
1

複数のスレッドで複数のIOLoopを実行しようとしていますが、IOLoopが実際にどのように動作するのか不思議です。マルチスレッドのTornado multiple 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で聞きますが、Webページをレンダリングすることはできません。私は何かが欠けているのだろうか、何かの方法でhttp_serverをIOLoopに結びつける必要があるのだろうか?

また、最後の3行を削除してtornado.ioloop.IOLoop.instance().startと置き換えると、1つのスレッドで完全に機能することがわかりました。しかし、シングルトンと自己作成IOLoopの違いは何ですか?

私は竜巻には新しく、どんな答えでも歓迎されます。

答えて

2

一般に、非同期オブジェクトを構築するときにはIOLoop.currentをデフォルトとして使用し、別のものからメインスレッドと通信することを意味する場合はIOLoop.instanceを使用する必要があります。 paramsなし

IOLoop.currentはスレッドのすでに作成ioloopを返すか、それがIOLoop.instance()を呼び出します。 HTTPServer(実際にはTCPServer)はIOLoop.currentをioloopとやりとりするため、変更する必要があるのはioloopをHTTPServerの前に作成することだけです。それは冗長なので

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がデフォルトで有効になっていないため、上記のコードは1つのスレッドのみで動作します。あなたがこれは素晴らしい答え、感謝です

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

代わりのhttp_server_api.listen(8888)

+0

でこれを有効にすることができ

OSError: [Errno 98] Address already in use 

:あなたは、で終わるだろう。私はhttp_serverが現在のIOLoopと対話していることを知らなかった。説明のためにとてもマッシュアップしてくれてありがとう。 –