簡體   English   中英

用Tornado Python進行異步函數調用

[英]Async function call with Tornado Python

我正在嘗試使用Tornado的gen.coroutine函數進行簡單的異步調用。 這是我當前的代碼:

from tornado import gen
import tornado.ioloop
import tornado.web


class MainHandler(tornado.web.RequestHandler):

    @gen.coroutine
    def get(self):
        q = self.get_argument('query')
        print q
        response = yield self.process(q)
        self.write(response)

    @gen.coroutine
    def process(self, query):
        # just a long loop
        for i in range(int(query)*100):
            for j in range(i):
                a = 10*10*10*10*10*10
        return {'processed': True}


def make_app():
    return tornado.web.Application([
        (r"/search", MainHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    port = 8888
    print "listening on port: ", port
    app.listen(port)
    tornado.ioloop.IOLoop.current().start()

但是,它不是以異步方式運行。 我在這方面做錯了什么?

您的“過程”方法僅進行計算,因此,在“過程”運行時,它永遠不會為Tornado的事件循環提供執行其他任務的機會。 龍卷風可以交錯並發網絡操作,但是,它不能並行運行Python代碼。 要並行化“過程”方法之類的函數,需要多個Python子過程。

您的函數正在阻塞事件循環,直到process()函數完成或將控制權交還給事件循環之前,其他任何任務都無法處理。 在這種情況下,您可以簡單地使用yield None (它以前是yield gen.moment )休息一下,讓事件循環運行其他任務,然后繼續處理。 例:

@gen.coroutine
def process(self, query):
    for i in range(int(query)*100):
        for j in range(i):
            a = 10*10*10*10*10*10
            if j % 500 == 0:
                yield None    # yield the inner loop

        if i % 500 == 0:
            yield None    # yield outer loop

    return {'processed': True}

希望這可以幫助您達到所需的並發水平。

參考

http://www.tornadoweb.org/en/stable/gen.html#tornado.gen.moment

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM