请求处理程序如下:
class TestHandler(tornado.web.RequestHandler): # localhost:8888/test
@tornado.web.asynchronous
def get(self):
t = threading.Thread(target = self.newThread)
t.start()
def newThread(self):
print "new thread called, sleeping"
time.sleep(10)
self.write("Awake after 10 seconds!")
self.finish()
class IndexHandler(tornado.web.RequestHandler): # localhost:8888/
def get(self):
self.write("It is not blocked!")
self.finish()
当我获取localhost:8888/test
时,页面加载10秒并显示Awake after 10 seconds
;在加载时,如果我在新的浏览器选项卡中打开localhost:8888/index
,则不会立即阻止和加载新的索引页面。这些符合我的期望。
但是,在加载/test
时,如果我在新的浏览器标签中打开另一个/test
,则会被阻止。第二个/test
仅在第一个完成后开始处理。
我在这里犯了什么错误?
答案 0 :(得分:7)
您所看到的实际上是浏览器限制,而不是代码问题。我在TestHandler
添加了一些额外的日志记录,以明确这一点:
class TestHandler(tornado.web.RequestHandler): # localhost:8888/test
@tornado.web.asynchronous
def get(self):
print "Thread starting %s" % time.time()
t = threading.Thread(target = self.newThread)
t.start()
def newThread(self):
print "new thread called, sleeping %s" % time.time()
time.sleep(10)
self.write("Awake after 10 seconds!" % time.time())
self.finish()
如果我同时打开两个curl会话到localhost / test,我会在服务器端得到这个:
Thread starting 1402236952.17
new thread called, sleeping 1402236952.17
Thread starting 1402236953.21
new thread called, sleeping 1402236953.21
这在客户端:
Awake after 10 seconds! 1402236962.18
Awake after 10 seconds! 1402236963.22
这正是您所期望的。但是在Chromium中,我得到了与你相同的行为。我认为Chromium(可能是所有浏览器)一次只允许一个连接打开到同一个URL。我通过使IndexHandler
运行与TestHandler
相同的代码来确认这一点,除了略有不同的日志消息。这是打开两个浏览器窗口时的输出,一个到/test
,一个到/index
:
index Thread starting 1402237590.03
index new thread called, sleeping 1402237590.03
Thread starting 1402237592.19
new thread called, sleeping 1402237592.19
正如你所看到的那样,两者同时没有问题。
答案 1 :(得分:0)
我认为您选择了“错误”测试来检查并行的GET
请求,这是因为您在测试中使用了 blocking 功能:time.sleep()
,当您仅呈现HTML页面时,行为并不会真正发生...
发生的事情是,当您使用def get()
时time.sleep
(处理所有GET请求)实际上被阻止了,它无法处理任何新的GET请求,从而将它们放入某种“队列”中
因此,如果您真的想测试sleep()
-使用龙卷风无阻塞函数:tornado.gen.sleep()
示例:
from tornado import gen
@gen.coroutine
def get(self):
yield self.time_wait()
@gen.coroutine
def time_wait(self):
yield gen.sleep(15)
self.write("done")
在浏览器中打开多个标签,然后您会看到所有请求到达时都在处理中,而不会“排队”出现在其中的新请求。