私は竜巻に非常に慣れていません。Tornado でブロックするリクエストを処理する方法を見ていました。ブロッキング コードを別のスレッドで実行します。ただし、スレッド化された関数が終了するまで、メインスレッドは引き続きブロックされます。ここでは gen.coroutine を使用していませんが、試してみましたが、結果は同じです
counter = 0
def run_async(func):
@wraps(func)
def function_in_a_thread(*args, **kwargs):
func_t = Thread(target=func, args=args, kwargs=kwargs)
func_t.start()
return function_in_a_thread
def long_blocking_function(index, sleep_time, callback):
print "Entering run counter:%s" % (index,)
time.sleep(sleep_time)
print "Exiting run counter:%s" % (index,)
callback('keyy' + index)
class FooHandler(tornado.web.RequestHandler):
@web.asynchronous
def get(self):
global counter
counter += 1
current_counter = str(counter)
print "ABOUT to spawn thread for counter:%s" % (current_counter,)
long_blocking_function(
index=current_counter,
sleep_time=5, callback=self.done_waiting)
print "DONE with the long function"
def done_waiting(self, response):
self.write("Whatever %s " % (response,))
self.finish()
class Application(tornado.web.Application):
def __init__(self):
handlers = [(r"/foo", FooHandler),
]
settings = dict(
debug=True,
)
tornado.web.Application.__init__(self, handlers, **settings)
def main():
application = Application()
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
if __name__ == "__main__":
main()
リクエストを連続して発行すると、FooHandler がブロックされ、long_blocking_function が終了するまでリクエストを受け取りません。だから私は次のようなものを見ることになります
ABOUT to spawn thread for counter:1
Entering run counter:1
Exiting run counter:1
DONE with the long function
ABOUT to spawn thread for counter:2
Entering run counter:2
Exiting run counter:2
DONE with the long function
ABOUT to spawn thread for counter:3
Entering run counter:3
Exiting run counter:3
DONE with the long function
これらの行に沿って何かを期待していましたが (long_blocking_function への最初の呼び出しが終了する前に複数の要求を発行しているため)、上記のようなトレースしか表示されません
ABOUT to spawn thread for counter:1
DONE with the long function
ABOUT to spawn thread for counter:2
DONE with the long function
ABOUT to spawn thread for counter:3
DONE with the long function
ABOUT to spawn thread for counter:4
DONE with the long function
Tornado が非同期リクエストをブロックするのを見て、両方のソリューションを試しました。しかし、同じハンドラーへの連続した要求でそれらを実行すると、両方ともブロックされます。誰かが私が間違っていることを理解できますか? トルネードがマルチスレッドでうまくいかないことは知っていますが、ブロックしない方法で新しいスレッドを実行できるはずです。