国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

tornado6與python3.7 異步新姿勢

maxmin / 1168人閱讀

摘要:這是我重新復習的原因放棄了之前自己實現的全面擁抱的這個改動是非常大的而且閱讀的源碼可以發現其中大部分函數都支持了類型檢驗和返回值提示值得閱讀

廢話不多說,直接上代碼
__auth__ = "aleimu"
__doc__ = "學習tornado6.0+ 版本與python3.7+"

import time
import asyncio
import tornado.gen
import tornado.web
import tornado.ioloop
import tornado.httpserver  # tornado的HTTP服務器實現
from tornado.options import define, options
from tornado.httpclient import HTTPClient, AsyncHTTPClient
from requests import get

settings = {"debug": True}
url = "http://127.0.0.1:5000/"  # 這是另個服務,請求5s后返回結果


# RuntimeError: Cannot run the event loop while another loop is running
# 解釋:HTTPClient內部寫 loop.run_xxx,因為那是啟動event loop的命令,通常只再最最最外面用一次,之后的代碼都應假設 loop 已經在運轉了。
def synchronous_fetch(url):
    print("synchronous_fetch")
    try:
        http_client = HTTPClient()
        time.sleep(5)
        response = http_client.fetch(url)
        print(response.body)
    except Exception as e:
        print("Error: " + str(e))
        return str(e)
    http_client.close()
    return response.body


# 替代synchronous_fetch的同步請求,沒有內置loop.run_xxx
def synchronous_get(url):
    response = get(url)
    time.sleep(5)
    print("synchronous_fetch")
    return response.text


# 簡單的模擬異步操作,這里之后應該替換成各種異步庫的函數
async def sleep():
    print("start sleep")
    await asyncio.sleep(5)
    print("end sleep")


# 異步請求
async def asynchronous_fetch(url):
    http_client = AsyncHTTPClient()
    response = await http_client.fetch(url)
    print("asynchronous_fetch")
    return response.body


# 測試
class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world:%s" % self.request.request_time())
        self.finish()
        print("not finish!")
        return


# 同步阻塞
class synchronous_fetcher(tornado.web.RequestHandler):
    def get(self):
        self.write("%s,%s" % (synchronous_fetch(url), self.request.request_time()))


# 同步阻塞
class synchronous_geter(tornado.web.RequestHandler):
    def get(self):
        self.write("%s,%s" % (synchronous_get(url), self.request.request_time()))


# 異步阻塞,我以為curl "127.0.0.1:8888/1" 總耗時希望為5s,可是是25s,看來異步沒搞好,以下的函數都是基于此改進的
class asynchronous_fetcher_1(tornado.web.RequestHandler):
    async def get(self):
        body = await asynchronous_fetch(url)
        for i in range(3):
            print("skip %s" % i)
            await tornado.gen.sleep(5)
        time.sleep(5)
        print("end request")
        self.write("%s,%s" % (body, self.request.request_time()))

# curl "127.0.0.1:8888/1"
# b"{
  "data": "123"
}
",25.026000022888184


# 異步阻塞,效果同上,這里只是證明 tornado.gen.sleep(5)和asyncio.sleep(5) 效果一致
class asynchronous_fetcher_2(tornado.web.RequestHandler):
    async def get(self):
        body = await asynchronous_fetch(url)  # 關注協程完成后返回的結果
        for i in range(3):
            print("skip %s" % i)
            await sleep()
        time.sleep(5)
        print("end request")
        self.write("%s,%s" % (body, self.request.request_time()))

# curl "127.0.0.1:8888/2"
# b"{
  "data": "123"
}
",25.039999961853027


# 異步非阻塞-將部分異步操作放入組中,實現loop管理
class asynchronous_fetcher_3(tornado.web.RequestHandler):
    async def get(self):
        body = await asynchronous_fetch(url)
        await asyncio.wait([sleep() for i in range(3)])
        print("end request")
        self.write("%s,%s" % (body, self.request.request_time()))

# curl "127.0.0.1:8888/3"
# b"{
  "data": "123"
}
",10.001000165939331

# 異步非阻塞-將所有異步操作放入組中,實現loop管理
class asynchronous_fetcher_4(tornado.web.RequestHandler):
    async def get(self):
        task_list = [sleep() for i in range(3)]
        task_list.append(asynchronous_fetch(url))
        body = await asyncio.wait(task_list)  # 將所有異步操作的結果返回,但是是無序的,要是需要返回結果的話解析起來比較麻煩
        print("end request:", body)
        # print(type(body), len(body),type(body[0]),len(body[0]),type(body[0]))
        self.write("%s,%s" % ([x.result() for x in body[0] if x.result() is not None][0],
                              self.request.request_time()))
# curl "127.0.0.1:8888/4"
# b"{
  "data": "123"
}
",5.006999969482422

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
        (r"/1", asynchronous_fetcher_1),
        (r"/2", asynchronous_fetcher_2),
        (r"/3", asynchronous_fetcher_3),
        (r"/4", asynchronous_fetcher_4),
        (r"/5", synchronous_fetcher),
        (r"/6", synchronous_geter),

    ], **settings)


if __name__ == "__main__":
    print("server start!")
    app = make_app()
    server = tornado.httpserver.HTTPServer(app)
    server.bind(8888)
    server.start(1)  # forks one process per cpu,windows上無法fork,這里默認為1
    tornado.ioloop.IOLoop.current().start()
總結
1.Tornado使用單線程事件循環,寫的不好,會阻塞的非常嚴重,比如synchronous_geter
2.flask+celery可以完成常見的異步任務
3.await語法只能出現在通過async修飾的函數中
4.可以看到tornado.gen.coroutine, tornado.concurrent.run_on_executor,tornado.web.asynchronous,tornado.gen.coroutine等這些裝飾器都不在經常使用了,都由async和await代替
參考文檔:
https://zhuanlan.zhihu.com/p/27258289   # Python async/await入門指南
http://www.tornadoweb.org/en/stable/guide/intro.html    # 這個官網
https://www.osgeo.cn/tornado/guide/intro.html   #Tornado 1.0 - Tornado 6.0的更新說明,以及6.0版本的中文文檔,適合英語不好的人閱讀
https://www.osgeo.cn/tornado/releases/v5.0.0.html#  在Python 3上, IOLoop 總是包裝asyncio事件循環。

On Python 3, IOLoop is always a wrapper around the asyncio event loop.
這是我重新復習tornado的原因,tornado放棄了之前自己實現的tornado.ioloop,全面擁抱asyncio的event_loop.這個改動是非常大的,
而且閱讀tornado的源碼可以發現其中大部分函數都支持了類型檢驗,和返回值提示,值得閱讀.

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/43783.html

相關文章

  • 異步讀取文件的幾種姿勢

    摘要:臆想的針對讀取到的內容進行操作,比如打印文件內容臆想中,讀取文件是有返回值的,將返回值,即文件內容,賦給一個變量,然后決定對讀取到的內容進行相應的操作,例如打印文件中的內容。 臆想的 let fs = require(fs) function readFile(filename){ ... } let content = readFile(config.js) // 針對讀...

    chinafgj 評論0 收藏0
  • MongoDB 4.0 Python3.7 穩定高效的評分制IP代理池APIserver

    摘要:項目的主要運行部分,采集器驗證器打分檢測等功能實現的模塊。在中可以配置異步的并發量等來控制驗證器。調用有了穩定的高分代理數據,那么就可以掛起一個為我們的爬蟲保駕護航,這一部分可以單獨拿出來編寫,使用其他框架之類的都是不錯的選擇。 FooProxy 穩健高效的評分制 IP代理池 + API服務提供,可以自己插入采集器進行代理IP的爬取,支持 MongoDB 4.0 使用 Python3....

    wangjuntytl 評論0 收藏0
  • MongoDB 4.0 Python3.7 穩定高效的評分制IP代理池APIserver

    摘要:項目的主要運行部分,采集器驗證器打分檢測等功能實現的模塊。在中可以配置異步的并發量等來控制驗證器。調用有了穩定的高分代理數據,那么就可以掛起一個為我們的爬蟲保駕護航,這一部分可以單獨拿出來編寫,使用其他框架之類的都是不錯的選擇。 FooProxy 穩健高效的評分制 IP代理池 + API服務提供,可以自己插入采集器進行代理IP的爬取,支持 MongoDB 4.0 使用 Python3....

    AndroidTraveler 評論0 收藏0
  • 處理JavaScript異常的正確姿勢

    摘要:我們使用單元測試來驗證一下我們使用了配合做單元測試。我們編寫相應的單元測試你會發現,如果出現異常,只是簡單的返回。但是在上面異常拋出的時候,解釋器已經不在中了,因此無法被捕獲。 譯者按: 錯誤是無法避免的,妥善處理它才是最重要的! 原文: A Guide to Proper Error Handling in JavaScript Related Topics: 譯者: Funde...

    lushan 評論0 收藏0
  • 前端基礎

    摘要:談起閉包,它可是兩個核心技術之一異步基于打造前端持續集成開發環境本文將以一個標準的項目為例,完全拋棄傳統的前端項目開發部署方式,基于容器技術打造一個精簡的前端持續集成的開發環境。 這一次,徹底弄懂 JavaScript 執行機制 本文的目的就是要保證你徹底弄懂javascript的執行機制,如果讀完本文還不懂,可以揍我。 不論你是javascript新手還是老鳥,不論是面試求職,還是日...

    graf 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<