这个让我有点困惑。 对 python 中的龙卷风和线程相当陌生,所以我可能完全偏离了我在这里尝试做的事情。
可能最好从一些简化的代码开始:
class Handler(tornado.web.RequestHandler):
def perform(self):
#do something cuz hey, we're in a thread!
def initialize(self):
self.thread = None
@tornado.web.asynchronous
def post(self):
self.thread = threading.Thread(target=self.perform)
self.thread.start()
self.write('In the request')
self.finish()
def on_connection_close(self):
logging.info('In on_connection_close()')
if self.thread:
logging.info('Joining thread: %s' % (self.thread.name))
self.thread.join()
我的问题是on_connection_close
永远不会被调用,请求得到很好的处理。 其次,我是否在以这种方式引入线程时做了什么可怕的事情?
Thread.join()
会阻塞直到线程完成,这可能是你想避免的事情。您可以对处理程序进行线程回调,而不是联接。
使用线程时,请注意 tornado 不是线程安全的,因此不能从线程使用任何 RequestHandler(例如)方法。
这对我有用:
import functools
import time
import threading
import logging
import tornado.web
import tornado.websocket
import tornado.locale
import tornado.ioloop
class Handler(tornado.web.RequestHandler):
def perform(self, callback):
#do something cuz hey, we're in a thread!
time.sleep(5)
output = 'foo'
tornado.ioloop.IOLoop.instance().add_callback(functools.partial(callback, output))
def initialize(self):
self.thread = None
@tornado.web.asynchronous
def get(self):
self.thread = threading.Thread(target=self.perform, args=(self.on_callback,))
self.thread.start()
self.write('In the request')
self.flush()
def on_callback(self, output):
logging.info('In on_callback()')
self.write("Thread output: %s" % output)
self.finish()
application = tornado.web.Application([
(r"/", Handler),
])
if __name__ == "__main__":
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
您可以使用 curl --no-buffer localhost:8888
.某些浏览器(Safari)似乎在显示任何输出之前等待连接关闭,这让我失望了一段时间。
AFAIK,仅当客户端终止连接时才调用on_connection_close
,这可能会解释您的问题。关于线程,我不知道你想做什么,但我不明白你为什么要在 Tornado 请求中创建线程,因为 Tornado 的优点之一就是你不必使用线程。如果我在您的示例中添加一个join
,我会将其放在self.finish()
之前,但是,您可能可以省略它......这将取决于您要对线程执行的操作,但请记住,Tornado 是单线程的,如果线程在join()
到来时尚未完成,整个过程将阻塞。