摘要:上一篇文章第一章異步及協(xié)程基礎(chǔ)第二節(jié)關(guān)鍵字下一篇文章第二章實戰(zhàn)演練開發(fā)網(wǎng)站第一節(jié)網(wǎng)站結(jié)構(gòu)使用協(xié)程可以開發(fā)出類似同步代碼的異步行為。協(xié)程函數(shù)可以通過以下三張方式調(diào)用在本身是協(xié)程的函數(shù)內(nèi)通過關(guān)鍵字調(diào)用。
上一篇文章:Python:Tornado 第一章:異步及協(xié)程基礎(chǔ):第二節(jié):Python關(guān)鍵字yield
下一篇文章:Python:Tornado 第二章:實戰(zhàn)演練:開發(fā)Tornado網(wǎng)站:第一節(jié):網(wǎng)站結(jié)構(gòu):HelloWorld
使用Tornado協(xié)程可以開發(fā)出類似同步代碼的異步行為。同時,因為協(xié)程本身不使用線程,所以減少了線程上下文切換的開銷,是一種高效的開發(fā)模式。
1、編寫協(xié)程函數(shù)實例:用協(xié)程技術(shù)開發(fā)網(wǎng)頁訪問功能
#用協(xié)程技術(shù)開發(fā)網(wǎng)頁訪問功能 from tornado import gen #引入?yún)f(xié)程庫gen from tornado.httpclient import AsyncHTTPClient import time #使用gen.coroutine修飾器 @gen.coroutine def coroutine_visit(): http_client=AsyncHTTPClient() response=yield http_client.fetch("http://www.baidu.com") print(response.body)
本例中任然使用了異步客戶端AsyncHTTPClient進(jìn)行頁面訪問,裝飾器@gen.coroutine聲明這是一個協(xié)程函數(shù),由于yield關(guān)鍵字的作用,使得代碼中不用再編寫回調(diào)函數(shù)用于處理訪問結(jié)果,而可以直接在yield語句的后面編寫結(jié)果處理語句。
2、調(diào)用協(xié)程函數(shù)由于Tornado協(xié)程基于Python的yield關(guān)鍵字實現(xiàn),所以不能像普通函數(shù)那樣直接調(diào)用。
協(xié)程函數(shù)可以通過以下三張方式調(diào)用:
在本身是協(xié)程的函數(shù)內(nèi)通過yield關(guān)鍵字調(diào)用。
在IOLoop尚未啟動時,通過IOLoop的run_sync()函數(shù)調(diào)用。
在IOLoop已經(jīng)啟動時,通過IOLoop的spawn_callback()函數(shù)調(diào)用。
代碼:
#用協(xié)程技術(shù)開發(fā)網(wǎng)頁訪問功能 from tornado import gen #引入?yún)f(xié)程庫gen from tornado.httpclient import AsyncHTTPClient import time #使用gen.coroutine修飾器 @gen.coroutine def coroutine_visit(): http_client=AsyncHTTPClient() response=yield http_client.fetch("http://www.baidu.com") print(response.body) @gen.coroutine def outer_coroutine(): print("start call coroutine_visit") yield coroutine_visit() print("end call coroutine_cisit")
本例中outer_coroutine()和coroutine_visit()都是協(xié)程函數(shù),所以他們之間可以通過yield關(guān)鍵字調(diào)用。_
IOLoop是Tornado的主事件循環(huán)對象,Tornado程序通過它監(jiān)聽外部客戶端的訪問請求,并執(zhí)行相應(yīng)操作。
代碼:
#用協(xié)程技術(shù)開發(fā)網(wǎng)頁訪問功能 from tornado import gen #引入?yún)f(xié)程庫gen from tornado.httpclient import AsyncHTTPClient from tornado.ioloop import IOLoop #引入IOLoop對象 #使用gen.coroutine修飾器 @gen.coroutine def coroutine_visit(): http_client=AsyncHTTPClient() response=yield http_client.fetch("http://www.baidu.com") print(response.body) def func_normal(): print("start call coroutine_visit") IOLoop.current().run_sync(lambda :coroutine_visit()) print("end call coroutine_visit")
當(dāng)程序尚未進(jìn)入IOLoop的running狀態(tài)時,可以通過run_sync()函數(shù)調(diào)用協(xié)程函數(shù)。??注意:run_sync()函數(shù)將阻塞當(dāng)前函數(shù)的調(diào)用,直到被調(diào)用的協(xié)程執(zhí)行完成。
事實上,Tornado要求協(xié)程函數(shù)在IOLoop的running狀態(tài)種才能被調(diào)用,只不過run_sync函數(shù)自動完成了啟動、停止IOLoop的操作步驟,他的實現(xiàn)邏輯是:
【啟動IOLoop】》【調(diào)用被lambda封裝的協(xié)程函數(shù)】》【停止IOLoop】
代碼:
#用協(xié)程技術(shù)開發(fā)網(wǎng)頁訪問功能 from tornado import gen #引入?yún)f(xié)程庫gen from tornado.httpclient import AsyncHTTPClient from tornado.ioloop import IOLoop #引入IOLoop對象 #使用gen.coroutine修飾器 @gen.coroutine def coroutine_visit(): http_client=AsyncHTTPClient() response=yield http_client.fetch("http://www.baidu.com") print(response.body) def func_normal(): print("start call coroutine_visit") IOLoop.current().spawn_callback(coroutine_visit) print("end call coroutine_visit")
spawn_callback()函數(shù)將不會等待被調(diào)用協(xié)程執(zhí)行完成,所有上下兩條打印語句將馬上完成,而coroutine__visit本身將會由IOLoop在合適的時機進(jìn)行調(diào)用。3、在協(xié)程中調(diào)用阻塞函數(shù)??注意:IOLoop的spawn_callback()函數(shù)沒有為開發(fā)者提供獲取協(xié)程函數(shù)調(diào)用返回值的方法,所以只能用span_callback()調(diào)用沒有返回值的協(xié)程函數(shù)。
在協(xié)程中直接調(diào)用阻塞函數(shù)會影響協(xié)程本身的性能,所以Tornado提供了在協(xié)程中利用線程池調(diào)度阻塞函數(shù),從而不影響協(xié)程本身繼續(xù)執(zhí)行的方法。
代碼實例:
from concurrent.futures import ThreadPoolExecutor from tornado import gen #定義線程池 thread_pool=ThreadPoolExecutor(2) def mySleep(count): import time for x in range(count): time.sleep(1) @gen.coroutine def call_blocking(): print("start") yield thread_pool.submit(mySleep,10) print("end")
代碼中首先引用了concurrent.futures種的ThreadPoolExecutor類,實例化了一個由兩個線程的線程池thread_pool。在需要調(diào)用阻塞函數(shù)的協(xié)程call_blocking種,使用thread_pool.submit調(diào)用阻塞函數(shù),并通過yield返回。這樣便不會阻塞協(xié)程所在的線程的繼續(xù)執(zhí)行,也保證了阻塞函數(shù)前后代碼的執(zhí)行順序。
4、在協(xié)程中等待多個異步調(diào)用到目前為止,我們知道了協(xié)程中一個yield關(guān)鍵字等待一個異步調(diào)用的編程方法。其實,Tornado允許在協(xié)程中用一個yield關(guān)鍵字等待多個異步調(diào)用,只需要把這些調(diào)用以列表(list)或字典(dictionary)的方式傳遞給yield關(guān)鍵字即可。
#使用列表方式傳遞多個異步調(diào)用 from tornado import gen #引入?yún)f(xié)程庫gen from tornado.httpclient import AsyncHTTPClient @gen.coroutine #使用gen.coroutine修飾器 def coroutine_visit(): http_client=AsyncHTTPClient() list_response=yield [ http_client.fetch("http://www.baidu.com"), http_client.fetch("http://www.api.jiutouxiang.com") ] for response in list_response: print(response.body)
在代碼中仍然使用@gen.coroutine裝飾器定義協(xié)程,在需要yield的地方用列表傳遞若干個異步調(diào)用,只有在列表種的所有調(diào)用都執(zhí)行完成后,yield才會返回并且繼續(xù)執(zhí)行。yield以列表方式返回調(diào)用結(jié)果。
#使用列表方式傳遞多個異步調(diào)用 from tornado import gen #引入?yún)f(xié)程庫gen from tornado.httpclient import AsyncHTTPClient @gen.coroutine #使用gen.coroutine修飾器 def coroutine_visit(): http_client=AsyncHTTPClient() dict_response=yield { "baidu": http_client.fetch("http://www.baidu.com"), "9siliao":http_client.fetch("http://www.api.jiutouxiang.com") } print(dict_response["baidu"].body)
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/42598.html
摘要:在種,使用關(guān)鍵字定義的迭代器也被稱為生成器迭代器迭代器是訪問集合內(nèi)元素的一種方式。調(diào)用任何定義包含關(guān)鍵字的函數(shù)都不會執(zhí)行該函數(shù),而是會獲得一個隊?wèi)?yīng)于該函數(shù)的迭代器。 上一篇文章:Python:Tornado 第一章:異步及協(xié)程基礎(chǔ):第一節(jié):同步與異步I/O下一篇文章:Python:Tornado 第一章:異步及協(xié)程基礎(chǔ):第三節(jié):協(xié)程 協(xié)程是Tornado中進(jìn)行異步I/O代碼開發(fā)的方法...
摘要:上一篇文章開篇下一篇文章第一章異步及協(xié)程基礎(chǔ)第二節(jié)關(guān)鍵字協(xié)程是種推薦的編程方式,使用協(xié)程可以開發(fā)出簡捷高效的異步處理代碼。同步操作,導(dǎo)致進(jìn)程阻塞,直到操作完成異步操作,不會導(dǎo)致請求進(jìn)程阻塞。 上一篇文章:Python:Tornado 開篇下一篇文章:Python:Tornado 第一章:異步及協(xié)程基礎(chǔ):第二節(jié):Python關(guān)鍵字yield 協(xié)程是Tornado種推薦的編程方式,使用協(xié)...
摘要:上一篇文章第一章異步及協(xié)程基礎(chǔ)第三節(jié)協(xié)程下一篇文章第二章實戰(zhàn)演練開發(fā)網(wǎng)站第二節(jié)網(wǎng)站結(jié)構(gòu)路由解析實例瀏覽器輸入鏈接頁面顯示下面逐行解析上面的代碼做了些什么首先通過語句引入包中的和類。該對象的第一個餐食用于定義程序的路由映射。 上一篇文章:Python:Tornado 第一章:異步及協(xié)程基礎(chǔ):第三節(jié):協(xié)程下一篇文章:Python:Tornado 第二章:實戰(zhàn)演練:開發(fā)Tornado網(wǎng)站:第...
摘要:作為網(wǎng)站的基礎(chǔ)框架,于年月日發(fā)布,目前已經(jīng)獲得了很多社區(qū)的支持,并且在一系列不同的場景種得到應(yīng)用。使用該框架,開發(fā)者能夠快速開發(fā)出即安全又強大的用戶身份認(rèn)證機制,例如機制用戶身份認(rèn)證防止跨站攻擊等等。 下一篇文章:Python:Tornado 第一章:異步及協(xié)程基礎(chǔ):第一節(jié):同步與異步I/O Tornado是一個可擴展的非阻塞Web服務(wù)器以及相關(guān)工具的總稱。Tornado每秒可以處理...
摘要:譯者說于年月日發(fā)布,該版本正式支持的關(guān)鍵字,并且用舊版本編譯同樣可以使用這兩個關(guān)鍵字,這無疑是一種進(jìn)步。其次,這是最后一個支持和的版本了,在后續(xù)的版本了會移除對它們的兼容。 譯者說 Tornado 4.3于2015年11月6日發(fā)布,該版本正式支持Python3.5的async/await關(guān)鍵字,并且用舊版本CPython編譯Tornado同樣可以使用這兩個關(guān)鍵字,這無疑是一種進(jìn)步。其次...
閱讀 2732·2021-09-22 15:58
閱讀 2258·2019-08-29 16:06
閱讀 933·2019-08-29 14:14
閱讀 2843·2019-08-29 13:48
閱讀 2485·2019-08-28 18:01
閱讀 1547·2019-08-28 17:52
閱讀 3352·2019-08-26 14:05
閱讀 1660·2019-08-26 13:50