ホームページ  >  記事  >  バックエンド開発  >  Python での Tornado コルーチンの使用方法の詳細な説明 (例付き)

Python での Tornado コルーチンの使用方法の詳細な説明 (例付き)

不言
不言転載
2018-10-16 16:03:533934ブラウズ
この記事では、Python での Tornado コルーチンの使用方法を詳しく説明します (例を示します)。これには一定の参考価値があります。必要な友人は参照できます。お役に立てば幸いです。

Tornado コルーチンを使用すると、同期コードと同様の非同期動作を開発できます。同時に、コルーチン自体はスレッドを使用しないため、スレッドのコンテキスト切り替えのオーバーヘッドが軽減され、効率的な開発モデルとなります。

1. コルーチン関数を作成する

例: コルーチン テクノロジを使用した Web ページ アクセス関数の開発

#用协程技术开发网页访问功能
from tornado import  gen #引入协程库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 が引き続き使用されます。デコレータ @gen.coroutine は、これがコルーチン関数であることを宣言します。 yield キーワードがあるため、アクセス結果を処理するためにコード内にコールバック関数を記述する必要はありません。代わりに、結果処理ステートメントを、利回りステートメント。

2. コルーチン関数を呼び出す

Tornado コルーチンは Python の yield キーワードに基づいて実装されているため、通常の関数のように直接呼び出すことはできません。
コルーチン関数は、次の 3 つの方法で呼び出すことができます。

  • それ自体がコルーチンである関数内で、yield キーワードを介して呼び出されます。

  • IOLoop が起動していない場合は、IOLoop の run_sync() 関数を通じて呼び出します。

  • IOLoop が開始されると、IOLoop の spawn_callback() 関数を通じて呼び出されます。

例: コルーチン関数を通じてコルーチン関数を呼び出す

コード:

#用协程技术开发网页访问功能
from tornado import  gen #引入协程库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() は両方ともコルーチン関数 プログラム関数。yield キーワードを通じて呼び出すことができます。 __

例: IOLoo が起動していない場合は、IOLoop の run_sync() 関数を通じて呼び出します。
IOLoop は Tornado のメイン イベント ループ オブジェクトであり、Tornado プログラムはこれを通じて外部クライアントからのアクセス要求をリッスンし、対応する操作を実行します。

コード:

#用协程技术开发网页访问功能
from tornado import  gen #引入协程库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")
プログラムが IOLoop の実行状態に入っていない場合、run_sync() 関数を通じてコルーチン関数を呼び出すことができます。

注: run_sync() 関数は、呼び出されたコルーチンの実行が完了するまで、現在の関数の呼び出しをブロックします。

実際、Tornado では IOLoop の実行状態でコルーチン関数を呼び出すことができる必要がありますが、run_sync 関数は IOLoop の開始と停止のステップを自動的に完了します。その実装ロジックは次のとおりです:

[IOLoop を開始する]》[ラムダによってカプセル化されたコルーチン関数を呼び出す]》[IOLoop を停止する]

例: IOLoop が開始されるとき、spawn_callback() 関数を介して呼び出します

コード:

#用协程技术开发网页访问功能
from tornado import  gen #引入协程库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() 関数は、呼び出されたコルーチンの実行が完了するまで待機しません。上位および下位のすべての print ステートメントはすぐに完了し、coroutine__visit 自体は次の時点で IOLoop によって呼び出されます。適切な時期。

注: IOLoop の spawn_callback() 関数は、コルーチン関数呼び出しの戻り値を取得するメソッドを開発者に提供しないため、span_callback() は戻り値のないコルーチン関数を呼び出すためにのみ使用できます。

3. コルーチンでのブロック関数の呼び出し

コルーチンでブロック関数を直接呼び出すと、コルーチン自体のパフォーマンスに影響を与えるため、Tornado ではスレッド プールを使用して、コルーチンでブロック関数をスケジュールすることができます。したがって、コルーチン自体の継続的な実行に影響を与えないメソッドです。

コード例:

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 クラスを参照し、2 つのスレッドで構成されるスレッド プール thread_pool をインスタンス化します。ブロッキング関数を呼び出す必要があるコルーチン call_blocking では、thread_pool.submit を使用してブロッキング関数を呼び出し、yield を通じてそれを返します。これにより、コルーチンが配置されているスレッドの継続的な実行がブロックされず、ブロック関数の前後のコードの実行順序も保証されます。

4. コルーチン内で複数の非同期呼び出しを待機する

これまでのところ、コルーチン内で yield キーワードを使用して非同期呼び出しを待機するプログラミング方法がわかりました。実際、Tornado では、コルーチンで yield キーワードを使用して複数の非同期呼び出しを待機することができ、これらの呼び出しをリストまたは辞書の形式で yield キーワードに渡すだけで済みます。
例: list メソッドを使用して複数の非同期呼び出しを渡す
#使用列表方式传递多个异步调用
from tornado import gen  #引入协程库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 デコレータを使用してコード内でコルーチンを定義し、yield が必要な場所にリストを使用していくつかの呼び出しを渡します非同期呼び出しである yield は、リスト内のすべての呼び出しが完了した後にのみ戻り、実行を継続します。 yield は呼び出し結果をリストで返します。

例: 辞書モードで複数の非同期呼び出しを渡す:
#使用列表方式传递多个异步调用
from tornado import gen  #引入协程库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)

以上がPython での Tornado コルーチンの使用方法の詳細な説明 (例付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。