Pythonプログラミング:asyncioライブラリ実現コモン非同期I/O同時-基礎概念


Pythonプログラミング:asyncioライブラリ実現コモン非同期I/O同時-基礎概念
AsyncioライブラリはPyPlから最初に提供され、Python 3で提供された.4標準ライブラリに導入され、私がasyncioを勉強している間にPythonは3.8を更新しました.この時、asyncioのAPIはすでに定格化されていました.古いバージョンに比べて、多くの文法糖が増加し、非同期プログラミングをより便利に実現しました.Pythonを3.7以上に更新して勉強することをお勧めします.
GIL(グローバル解釈ロック)が存在するため、Pythonは1回の実行中に1つのプロセスしか実行できないため、IOブロックやコードの実行速度が遅いという問題が発生し、マルチプロセス/マルチスレッドベースのサードパーティライブラリが多いが、Pythonの性能上の先天的な不足を補うことができず、asyncioはコモン非同期I/Oに基づいてイベントの同時実行を実現する.geventに依存しないで、GILの性能に対する制限を破って、あなたはasync/await文法を通じて原生の協程コードを構築することができます.
簡単なHello Worldの例から協力の旅を始めます.
import asyncio

async def main():    #    async             (coroutines)
    print('Hello')
    # await         coroutines          awaitable   
    await asyncio.sleep(1)    #    1s
    print('World')
    
asyncio.run(main())    #    .run()         
#     :
--> Hello
--> World

この例では、1つのHelloを印刷し、1 s待ってからWorldを印刷する関数をasyncキーワードで宣言するが、main()で呼び出すことができず、asyncioを使用する必要があることに注意する.run(main()は、コヒーレントを実行することができます.コヒーレント/コヒーレントオブジェクトのエントリとして理解できます.理想的には、呼び出されるのは1回だけです.
オブジェクトがawait文で使用できる場合、それは待機可能(awaitable)オブジェクトであり、待機可能オブジェクトには3つの主要なタイプがあります:協程、タスク、Future.
きょうてい
Pythonコンシステントは待機可能なオブジェクトに属するため、他のコンシステントで待機できます.
import asyncio
import time

async def hello():    #      hello   
    await asyncio.sleep(1)
    print('Hello')
   
async def world():    #      world   
    await asyncio.sleep(2)
    print('World')
   
async def main():    #      main   
    print(f'started at {time.strftime("%X")}')
    await hello()
    await world()    #   main           hello()     world()
    print(f'finished at {time.strftime("%X")}')
   
asyncio.run(main())    #    main()   
#     :
--> started at 14:54:25
--> Hello
--> World
--> finished at 14:54:28    #        3s

注:asyncioの公式ドキュメントでは、コパスは2つの密接に関連する概念を表すために使用されます.コパス関数:asyncキーワードで宣言されたコパス関数コパスオブジェクト:コパス関数を呼び出して返されるオブジェクト
タスク#タスク#
コンセンサスがasyncioを通過するとcreate_task()などの関数が1つのタスク(task)にパッケージ化されると、このコラボレーションは自動的にスケジュールに組み込まれます.上記のコラボレーションの例では、main()に2つのコラボレーションを書き込み、印刷時間からこの2つのコラボレーションが前後して実行されることがわかります.次に、この動作をタスクにパッケージして再実行してみます.
import asyncio
import time

async def hello():    #      hello   
    await asyncio.sleep(1)
    print('Hello1')
    await asyncio.sleep(2)
    print('Hello3')
   
async def world():    #      world   
    await asyncio.sleep(2)
    print('World2')
   
async def main():    #      main   
    task1 = asyncio.create_task(hello())    #   hello       task1
    task2 = asyncio.create_task(world())    #   world       task2
    print(f'started at {time.strftime("%X")}')
    await task1
    await task2    #      task1 / task2
    print(f'finished at {time.strftime("%X")}')
   
asyncio.run(main())    #    main()   
#     :
--> started at 14:57:17
--> Hello1
--> World2
--> Hello3
--> finished at 14:57:20    #        3s

実行結果からasyncioを通過できることが分かった.create_task()関数はタスクをパッケージ化して複数のコラボレーションを実現し、asyncio.sleep()はasyncioに内蔵されたスリープ協程であり、現在のタスクを保留して他のタスクの許可を許可し、asyncioはasyncioを通じて他のタスクを同時に実行する方法を提供する.gather():
import asyncio
import time

async def hello():    #      hello   
    await asyncio.sleep(1)
    print('Hello1')
    await asyncio.sleep(2)
    print('Hello3')
   
async def world():    #      world   
    await asyncio.sleep(2)
    print('World2')
   
async def main():    #      main   
    print(f'started at {time.strftime("%X")}')
    await asyncio.gather(
        hello(),
        world()    #          aws
    )
    print(f'finished at {time.strftime("%X")}')
   
asyncio.run(main())    #    main()   
#     :
--> started at 15:12:23
--> Hello1
--> World2
--> Hello3
--> finished at 15:12:26    #        3s

gather()が受信したawsシーケンスのいずれかの待機可能オブジェクトがコヒーレントである場合、それは自動的にタスク参加同時に変換され、awsシーケンスのいずれかのTaskまたはFutureオブジェクトがキャンセルされると、CancelledErrorエラータイプが投げ出されますが、gather()の呼び出しはキャンセルされません.すでに提出されたTasks/Futureがキャンセルされた後、他のTasks/Futureもキャンセルされることを防止します.
Futures
トランザクションと呼びます.トランザクション(Future)は、非同期操作の最終結果を表す特殊な最下位レベルの待機オブジェクトです.Futureオブジェクトが待機している場合は、Futureオブジェクトが他の場所で実行されるかキャンセルされるまで、協程が待機していることを意味します.通常、Futureは、下位レベルのコールバックコードと上位レベルの非同期/待機コードとのインタラクションに使用されます.
コンシステント(coroture)、タスク(Task)、トランザクション(Future)はいずれも広義のコンシステントと見なすことができ、Taskはasyncioを使用すると理解できる.create_task()などの関数はcorotureをパッケージ化し、Futureはasyncioを使用する.gather()関数は、複数のTask(coroture)をgather()によって自動的にTaskに変換する)とFutureによってパッケージ化した大きなコヒーレンスであり、これらの待機可能なオブジェクトはawaitによって受け入れられる.