python非同期非同期ライブラリの使用手順

asyncioを学習する前に、まず同期/非同期の概念を明確にします。

同期とは、トランザクションを完了するロジックを指します。最初のトランザクションが最初に実行されます。ブロックされている場合は、トランザクションが完了するまで待機してから、2番目のトランザクションを順番に実行します。

非同期とは、同期の反対です。非同期とは、呼び出し元のトランザクションを処理した後、このトランザクションの処理結果を待たずに、2番目のトランザクションを直接処理し、ステータス、通知、およびコールバックを通じて処理結果を呼び出し元に通知することを意味します。

非同期機能:

非同期IOはメッセージループモードを採用し、「メッセージの読み取り-メッセージの処理」のプロセスを繰り返します。つまり、非同期IOモデルには「メッセージループが必要であり、メインスレッドは「メッセージの読み取り-メッセージの処理」を繰り返します。このプロセス。

event_loop:プログラムは無限ループを開き、プログラマーはイベントループにいくつかの関数を登録します。満足のいくイベントが発生すると、対応するcoroutine関数が呼び出されます。

coroutine:coroutineオブジェクトは、asyncキーワードを使用して定義された関数を参照します。その呼び出しは、関数をすぐには実行しませんが、coroutineオブジェクトを返します。 coroutineオブジェクトは、イベントループに登録され、イベントループによって呼び出される必要があります。

タスクタスク:coroutineオブジェクトは、ネイティブに中断できる関数であり、タスクは、タスクのさまざまな状態を含むcoroutineをさらにカプセル化します。

async / awaitキーワード:coroutineを定義するために使用されるキーワード、asyncはcoroutineを定義し、awaitはブロックされた非同期呼び出しインターフェースを一時停止するために使用されます。

1つ、非同期

同期コードと非同期コードの記述の違いを比較する例を見てみましょう。次に、2つの間のパフォーマンスのギャップを確認します。asyncio.sleep(1)を使用して、1秒かかるio操作をシミュレートします。

同期コード:

import time

def hello():
 time.sleep(1)

def run():for i inrange(5):hello()print('Hello World:%s'% time.time())if __name__ =='__main__':run()

Hello World:1536842494.2786784
Hello World:1536842495.2796268
Hello World:1536842496.2802596
Hello World:1536842497.2804587
Hello World:1536842498.2812462

非同期コード:

import time
import asyncio

# 非同期関数を定義する
async def hello():print('Hello World:%s'% time.time())
 # 待機を使用する必要があります。yieldfromは使用できません。yieldfromを使用する場合は、@asyncio.コルティン対応
 await asyncio.sleep(1)print('Hello wow World:%s'% time.time())

def run():
 tasks =[]for i inrange(5):
 tasks.append(hello())
 loop.run_until_complete(asyncio.wait(tasks))

loop = asyncio.get_event_loop()if __name__ =='__main__':run()

Hello World:1536855050.1950748
Hello World:1536855050.1950748
Hello World:1536855050.1950748
Hello World:1536855050.1960726
Hello World:1536855050.1960726(約1秒間一時停止します)
Hello wow World:1536855051.1993241
Hello wow World:1536855051.1993241
Hello wow World:1536855051.1993241
Hello wow World:1536855051.1993241
Hello wow World:1536855051.1993241

async defは、内部に非同期操作を持つ非同期関数を定義するために使用されます。各スレッドにはイベントループがあります。メインスレッドがasyncio.get_event_loop()を呼び出すと、イベントループが作成され、このループのrun_until_complete()メソッドに非同期タスクがスローされます。イベントループは、協調プログラムの実行を調整します。

上記のプログラムでは、hello()は最初にHello world!を出力します。次に、構文からのyieldにより、別のジェネレーターを簡単に呼び出すことができます。

await asyncio.sleep(1)もコルーチンであるため、スレッドはasyncio.sleep(1)を待機せず、直接中断して次のメッセージループを実行します。

asyncio.sleep(1)が戻ると、スレッドはyieldから戻り値を取得し(ここではNone)、ステートメントの次の行を実行できます。

asyncio.sleep(1)を1秒かかるIO操作と考えてください。この間、メインスレッドは待機せず、EventLoopで他の実行可能なコルーチンを実行するため、同時実行を実現できます。

asyncio操作の要約:

async def hello():非同期非同期関数を定義します。途中にawait async.sleep(N)を追加して、割り込みを設定し、次のループメッセージを実行できます。

タスク= []タスクは、タスクのさまざまな状態を含むコルルーチンをさらにカプセル化することです。つまり、複数のcoroutine関数を一連のタスクにカプセル化して、同時に実行することができます。

loop = asyncio.get_event_loop()#「イベントループ」オブジェクトを取得します

loop.run_until_complete(asyncio.wait(tasks))#イベントループを介してcoroutine関数を呼び出します

loop.close()終了時間ループ

**2、aiohttp **

同時httpリクエストが必要な場合、通常はリクエストが使用されますが、リクエストは同期ライブラリです。非同期にする場合は、aiohttpを導入する必要があります。

ここでクラスを紹介するには、aiohttp import ClientSessionから、最初にセッションオブジェクトを作成し、次にセッションオブジェクトを使用してWebページを開きます。

セッションでは、post、get、put、headなどの複数の操作を実行できます。

基本的な使用法:

async with ClientSession() as session:
async with session.get(url) as response:

aiohttp非同期実装の例:

import asyncio
from aiohttp import ClientSession

tasks =[]
url ="https://www.baidu.com/{}"async def hello(url):asyncwithClientSession()as session:asyncwith session.get(url)as response:
  response =await response.read()print(response)if __name__ =='__main__':
 loop = asyncio.get_event_loop()
 loop.run_until_complete(hello(url))

まず、async defキーワードは、これが非同期関数であることを定義します。awaitキーワードは、待機する必要のある操作の前に追加されます。Response.read()は、IOを消費する操作である要求応答を待機します。次に、ClientSessionクラスを使用してhttp要求を開始します。

マルチリンク非同期アクセス

複数のURLを要求する必要がある場合はどうなりますか?複数のURLに同期的にアクセスするには、forループを追加するだけです。しかし、非同期の実装はそれほど簡単ではありません。前述に基づいて、hello()をasyncioのFutureオブジェクトでラップしてから、Futureオブジェクトのリストをタスクとしてイベントループに渡す必要があります。

import time
import asyncio
from aiohttp import ClientSession

tasks =[]
url ="https://www.baidu.com/{}"async def hello(url):asyncwithClientSession()as session:asyncwith session.get(url)as response:
  response =await response.read()print('Hello World:%s'% time.time())

def run():for i inrange(5):
 task = asyncio.ensure_future(hello(url.format(i)))
 tasks.append(task)if __name__ =='__main__':
 loop = asyncio.get_event_loop()run()
 loop.run_until_complete(asyncio.wait(tasks))

Hello World:1536843566.064149
Hello World:1536843566.070586
Hello World:1536843566.0769563
Hello World:1536843566.0779328
Hello World:1536843566.0799286

・http応答を収集

さて、さまざまなリンクにアクセスする非同期実装を上で紹介しましたが、リクエストを送信しただけです。応答を1つずつリストに収集し、最終的にローカルに保存するか、印刷する場合は、どのように実行しますか?asyncio.gatherを使用できます。 (*タスク)すべての回答を収集する

import time
import asyncio
from aiohttp import ClientSession

tasks =[]
url ="https://www.baidu.com/{}"async def hello(url):asyncwithClientSession()as session:asyncwith session.get(url)as response:
#  print(response)print('Hello World:%s'% time.time())returnawait response.read()

def run():for i inrange(5):
 task = asyncio.ensure_future(hello(url.format(i)))
 tasks.append(task)
 result = loop.run_until_complete(asyncio.gather(*tasks))print(result)if __name__ =='__main__':
 loop = asyncio.get_event_loop()run()

Hello World:1536843488.678779
Hello World:1536843488.6797836
Hello World:1536843488.6867576
Hello World:1536843488.6877556
Hello World:1536843488.6877556

python非同期非同期ライブラリを使用するための上記の手順は、エディタによって共有されるすべてのコンテンツです。参照を提供したいと思います。

Recommended Posts

python非同期非同期ライブラリの使用手順
14. MysSQL for Python3
Pythonを使用したハイパーパラメータの最適化
Python操作yaml命令