1. 程式人生 > >Tornado非同步與延遲任務

Tornado非同步與延遲任務

最近一直在研究Tornado非同步操作,然而一番研究後發現要使一個函式非同步化的最好方法就是採用相關非同步庫,但目前很多功能強大的庫都不在此列。經過一番查詢文件和搜尋示範,終於發現了ThreadPoolExecutor模組和run_on_executor裝飾器。用法就是建立執行緒池,用run_on_executor裝飾的函式即執行在其中執行緒中,從而從主執行緒中分離出來,達到非同步的目的。
另外,Tornado的IOLoop例項還有IOLoop.add_callback(callback, *args, **kwargs)方法,文件中的描述如下:

Calls the given callback on the next I/O loop iteration.
It is safe to call this method from any thread at any time, except from a signal handler. Note that this is the only

method in IOLoop
that makes this thread-safety guarantee; all other interaction with theIOLoop
must be done from that IOLoop
‘s thread. add_callback()
may be used to transfer control from other threads to the IOLoop
‘s thread.

意思就是在執行add_callback方法後馬上就會執行下一行程式碼,而callback函式將在下一輪事件迴圈中才呼叫,從而就能實現延遲任務。在Web APP中應付HTTP請求時,當有一些耗時操作並不需要返回給請求方時,就可以採用延遲任務的形式,比如傳送提醒郵件。
示範程式碼如下:

#!/bin/env python
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web import tornado.httpclient import tornado.gen from tornado.concurrent import run_on_executor # 這個併發庫在python3自帶;在python2需要安裝sudo pip install futures from concurrent.futures import ThreadPoolExecutor import time from tornado.options import define, options define("port", default=8002, help="run on the given port", type=int) class SleepHandler(tornado.web.RequestHandler): executor = ThreadPoolExecutor(2) def get(self): tornado.ioloop.IOLoop.instance().add_callback(self.sleep) # 這樣將在下一輪事件迴圈執行self.sleep self.write("when i sleep")  @run_on_executor def sleep(self): time.sleep(5) print("yes") return 5 if __name__ == "__main__": tornado.options.parse_command_line() app = tornado.web.Application(handlers=[ (r"/sleep", SleepHandler), ]) http_server = tornado.httpserver.HTTPServer(app) http_server.listen(options.port) tornado.ioloop.IOLoop.instance().start() 

小禮物走一走,來簡書關注我



作者:不問喂神馬
連結:https://www.jianshu.com/p/3d20a092588d
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。