<rp id="wnpn7"><ruby id="wnpn7"></ruby></rp>
<progress id="wnpn7"><track id="wnpn7"><rt id="wnpn7"></rt></track></progress>
<ruby id="wnpn7"></ruby>
<ruby id="wnpn7"><blockquote id="wnpn7"><div id="wnpn7"></div></blockquote></ruby>

    1. <em id="wnpn7"><ruby id="wnpn7"><input id="wnpn7"></input></ruby></em>
      1. <button id="wnpn7"><acronym id="wnpn7"></acronym></button><button id="wnpn7"><acronym id="wnpn7"></acronym></button>

        <rp id="wnpn7"><acronym id="wnpn7"></acronym></rp>

        <li id="wnpn7"><object id="wnpn7"><u id="wnpn7"></u></object></li>
        VB.net 2010 視頻教程 VB.net 2010 視頻教程 python基礎視頻教程
        SQL Server 2008 視頻教程 c#入門經典教程 Visual Basic從門到精通視頻教程
        當前位置:
        首頁 > 編程開發 > python教程 >
        • python基礎教程之Python3標準庫:asyncio異步I/O、事件循環和并發工具

        本站最新發布   Python從入門到精通|Python基礎教程
        試聽地址  
        http://www.squ68.com/eschool/python.html


        作者:@小灰灰
        本文為作者原創,轉載請注明出處:https://www.cnblogs.com/liuhui0308/p/12600076.html


        1. asyncio異步I/O、事件循環和并發工具

        asyncio模塊提供了使用協程構建并發應用的工具。threading模塊通過應用線程實現并發,multiprocessing使用系統進程實現并發,asyncio則使用一種單線程單進程方法來實現并發,應用的各個部分會彼此合作,在最優的時刻顯式地切換任務。大多數情況下,會在程序阻塞等待讀寫數據時發生這種上下文切換,不過asyncio也支持調度代碼在將來的某個特定時間運行,從而支持一個協程等待另一個協程完成,以處理系統信號和識別其他一些事件(這些事件可能導致應用改變其工作內容)。

        1.1 異步并發概念

        使用其他并發模型的大多數程序都采用線性方式編寫,而且依賴于語言運行時系統或操作系統的底層線程或進程管理來適當地改變上下文。基于asyncio的應用要求應用代碼顯式地處理上下文切換,要正確地使用相關技術,這取決于是否能正確理解一些相關聯的概念。asyncio提供的框架以一個事件循環(event loop)為中心,這是一個首類對象,負責高效地處理I/O事件、系統事件和應用上下文切換。目前已經提供了多個循環實現來高效地利用操作系統的功能。盡管通常會自動地選擇一個合理的默認實現,但也完全可以在應用中選擇某個特定的事件循環實現。在很多情況下這會很有用,例如,在Windows下,一些循環類增加了對外部進程的支持,這可能會以犧牲一些網絡I/O效率為代價。與事件循環交互的應用要顯式地注冊將運行的代碼,讓事件循環在資源可用時向應用代碼發出必要的調用。例如,一個網絡服務器打開套接字,然后注冊為當這些套接字上出現輸入事件時服務器要得到通知。事件循環在建立一個新的進入連接或者在數據可讀取時都會提醒服務器代碼。當前上下文中沒有更多工作可做時,應用代碼要再次短時間地交出控制。例如,如果一個套接字再沒有更多的數據可以讀取,那么服務器會把控制交回給事件循環。
        將控制交還給事件循環的機制依賴于Python的協程(coroutine),這是一些特殊的函數,可以將控制交回給調用者而不丟失其狀態。協程與生成器函數非常類似;實際上,在Python3.5版本之前對協程未提供原生支持時,可以用生成器來實現協程。asyncio還為協議(protocol)和傳輸(transport)提供了一個基于類的抽象層,可以使用回調編寫代碼而不是直接編寫協程。在基于類的模型和協程模型中,可以通過重新進入事件循環顯式地改

        變上下文,以取代Python多線程實現中隱式的上下文改變。future是一個數據結構,表示還未完成的工作結果。事件循環可以監視Future對象是否完成,從而允許應用的一部分等待另一部分完成一些工作。除了future,asyncio還包括其他并發原語,如鎖和信號量。
        Task是Future的一個子類,它知道如何包裝和管理一個協程的執行。任務所需的資源可用時,事件循環會調度任務運行,并生成一個結果,從而可以由其他協程消費。

        1.2 利用協程合作完成多任務

        協程是一個專門設計用來實現并發操作的語言構造。調用協程函數時會創建一個協程對象,然后調用者使用協程的send()方法運行這個函數的代碼。協程可以使用await關鍵字(并提供另一個協程)暫停執行。暫停時,這個協程的狀態會保留,使得下一次被喚醒時可以從暫停的地方恢復執行。

        1.2.1 啟動一個協程

        asyncio事件循環可以采用多種不同的方法啟動一個協程。最簡單的方法是使用run_until complete(),并把協程直接傳人這個方法。

        
        	
        1. import asyncio
        2.  
        3. async def coroutine():
        4. print('in coroutine')
        5.  
        6. event_loop = asyncio.get_event_loop()
        7. try:
        8. print('starting coroutine')
        9. coro = coroutine()
        10. print('entering event loop')
        11. event_loop.run_until_complete(coro)
        12. finally:
        13. print('closing event loop')
        14. event_loop.close()

        第一步是得到事件循環的一個引用。可以使用默認的循環類型,也可以實例化一個特定的循環類。在這個例子中使用了默認循環。run_until_complete()方法用這個協程啟動循環;協程返回退出時這個方法會停止循環。

        1.2.2 從協程返回值 

        協程的返回值傳回給啟動并等待這個協程的代碼。

        
        	
        1. import asyncio
        2.  
        3. async def coroutine():
        4. print('in coroutine')
        5. return 'result'
        6.  
        7. event_loop = asyncio.get_event_loop()
        8. try:
        9. return_value = event_loop.run_until_complete(
        10. coroutine()
        11. )
        12. print('it returned: {!r}'.format(return_value))
        13. finally:
        14. event_loop.close()

        在這里,run_unitil_complete()還會返回它等待的協程的結果。

        1.2.3 串鏈協程

        一個協程可以啟動另一個協程并等待結果,從而可以更容易地將一個任務分解為可重用的部分。下面的例子有兩個階段,它們必須按順序執行,不過可以與其他操作并發運行。

        
        	
        1. import asyncio
        2.  
        3. async def outer():
        4. print('in outer')
        5. print('waiting for result1')
        6. result1 = await phase1()
        7. print('waiting for result2')
        8. result2 = await phase2(result1)
        9. return (result1, result2)
        10.  
        11. async def phase1():
        12. print('in phase1')
        13. return 'result1'
        14.  
        15. async def phase2(arg):
        16. print('in phase2')
        17. return 'result2 derived from {}'.format(arg)
        18.  
        19. event_loop = asyncio.get_event_loop()
        20. try:
        21. return_value = event_loop.run_until_complete(outer())
        22. print('return value: {!r}'.format(return_value))
        23. finally:
        24. event_loop.close()

        這里使用了await關鍵字而不是向循環增加新的協程。因為控制流已經在循環管理的一個協程中,所以沒有必要告訴循環管理這些新協程。

        1.2.4 生成器代替協程 

        協程函數是asyncio設計中的關鍵部分。它們提供了一個語言構造,可以停止程序某一部分的執行,保留這個調用的狀態,并在以后重新進人這個狀態。所有這些動作都是并發框架很重要的功能。 Python3.5引入了一些新的語言特性,可以使用async def以原生方式定義這些協程,以及使用await交出控制,asyncio的例子利用了這些新特性。Python3的早期版本可以使用由 asyncio.coroutine()修飾符包裝的生成器函數和yield from來達到同樣的效果。

        
        	
        1. import asyncio
        2.  
        3. @asyncio.coroutine
        4. def outer():
        5. print('in outer')
        6. print('waiting for result1')
        7. result1 = yield from phase1()
        8. print('waiting for result2')
        9. result2 = yield from phase2(result1)
        10. return (result1, result2)
        11.  
        12. @asyncio.coroutine
        13. def phase1():
        14. print('in phase1')
        15. return 'result1'
        16.  
        17. @asyncio.coroutine
        18. def phase2(arg):
        19. print('in phase2')
        20. return 'result2 derived from {}'.format(arg)
        21.  
        22. event_loop = asyncio.get_event_loop()
        23. try:
        24. return_value = event_loop.run_until_complete(outer())
        25. print('return value: {!r}'.format(return_value))
        26. finally:
        27. event_loop
        相關教程
                
        免费看成年人视频大全_免费看成年人视频在线观看