這樣做的原因是,time.sleep
是阻塞功能:它不允許控制返回IOLoop
,使其他處理程序可以運行。
當然,time.sleep
通常只是這些示例中的佔位符,重點是要顯示處理程序中的某些內容變慢時會發生什麼。無論真正的代碼在做什麼,爲了實現併發性,阻塞代碼必須替換爲非阻塞等價物。這意味着三兩件事之一:
查找協程友好相當於。對於time.sleep,請改爲使用tornado.gen.sleep:
class CoroutineSleepHandler(RequestHandler):
@gen.coroutine
def get(self):
for i in range(5):
print(i)
yield gen.sleep(1)
當此選項可用時,通常是最佳方法。請參閱Tornado wiki以獲取可能有用的異步庫的鏈接。
查找基於回撥的等效物。類似於第一種選擇,基於回調的庫可用於許多任務,但它們比爲協程設計的庫稍微複雜一些。這些通常與tornado.gen.Task
用作適配器:
class CoroutineTimeoutHandler(RequestHandler):
@gen.coroutine
def get(self):
io_loop = IOLoop.current()
for i in range(5):
print(i)
yield gen.Task(io_loop.add_timeout, io_loop.time() + 1)
再次,Tornado wiki可以是有用的,以找到合適的庫。
在另一個線程上運行阻止碼。當異步庫不可用時,可以使用concurrent.futures.ThreadPoolExecutor
在另一個線程上運行任何阻塞碼。這是可用於任何阻擋功能的異步對方是否存在一個通用的解決方案:
executor = concurrent.futures.ThreadPoolExecutor(8)
class ThreadPoolHandler(RequestHandler):
@gen.coroutine
def get(self):
for i in range(5):
print(i)
yield executor.submit(time.sleep, 1)
參見龍捲風用戶指南的Asynchronous I/O chapter更多關於阻塞和異步函數。
我希望你能粘這個答案 –
這就是主意。這是複製[龍捲風常見問題](http://www.tornadoweb.org/en/stable/faq.html#why-isn-t-this-example-with-time-sleep-running-in-parallel)因此所有其他提出這個問題的問題都可以作爲這個問題的重複來解決。 –