Pythonのコルーチンを詳しく解説

王林
リリース: 2023-06-10 11:37:46
オリジナル
4456 人が閲覧しました

Python は、そのシンプルさ、学習の容易さ、幅広い用途のため、広く使用されている人気のあるプログラミング言語です。その中でもコルーチンは Python において非常に重要な概念であり、Python における非同期 IO プログラミングの基礎の 1 つです。この記事ではPythonのコルーチンについて詳しく解説します。

1. コルーチンとは何ですか?

コルーチンはユーザー モードの軽量スレッドであり、オペレーティング システムのスレッドよりも移植性が高くなります。プログラマがプログラム内で実装するため、コンテキスト切り替えのオーバーヘッドが発生せず、コルーチンの切り替えは外部からの介入なしにプログラム自身で完了し、スレッドの作成を削減し、CPUリソースをより効率的に使用できます。

コルーチンの特徴:

  1. は同じスレッド内で同時に実行でき、切り替えのオーバーヘッドが非常に小さいため、高い同時実行性をサポートします。
  2. コルーチンのステータスはプログラマ自身によって管理され、スレッドよりも軽量です。

2. コルーチンの実装

Python でコルーチンを実装するには、ジェネレーター、async/await、gevent と組み合わせる 3 つの方法があります。以下、一つずつご紹介していきます。

  1. ジェネレーター

Python のジェネレーター自体は、状態の保存と復元の機能を備えており、コルーチンの実装に非常に適しています。ジェネレーターコルーチンの最大の特徴は、yieldステートメントを使用して関数を一時停止し、関数の状態を保存することです。

次はコルーチンの例です:

def simple_coroutine():
    print('-> coroutine started')
    x = yield
    print('-> coroutine received:', x)

# 调用协程
my_coroutine = simple_coroutine()
print(my_coroutine)  # <generator object simple_coroutine at 0x7f6b25c43eb0>

# 先启动协程,让协程处于暂停状态。
next(my_coroutine)  # -> coroutine started

# 发送消息给协程,它会恢复执行,并打印出消息
my_coroutine.send('hello world')  # -> coroutine received: hello world
ログイン後にコピー

この例では、関数 simple_coroutine にはジェネレータ コルーチンの記号である yield 式が含まれています。関数が呼び出されるとき、これはジェネレーターオブジェクトを返します。プログラムは next() メソッドを呼び出してジェネレーターを最初の yield ステートメントに進め、「-> コルーチンが開始されました」というメッセージを出力します。次に、メッセージ「hello world」をジェネレーターに送信しました。これは変数 x に取り込まれ、「-> コルーチンを受け取りました: hello world」と出力されました。

  1. async/await

Python 3.5 以降、Python はコルーチンをサポートするネイティブ構文 async/await を提供します。これにより、構文がすっきりし、読みやすくなります。

次は async/await の例です:

import asyncio

async def countdown(n):
    while n > 0:
        print(f'T-minus {n}')
        await asyncio.sleep(1.0)
        n -= 1

asyncio.run(countdown(3))
ログイン後にコピー

この例では、async/await を使用すると、関数内でキーワード async を使用してコルーチンを定義し、await を使用して一時停止できます。コルーチンの手順。もちろん、async/await 構文を使用するには、asyncio ライブラリを使用する必要があります。

  1. gevent との併用

gevent は、コルーチンに基づく Python ネットワーク ライブラリであり、プログラマーが非同期の非ブロッキング コードを作成できるようにする、歩留まりベースのプログラミング モデルを提供します。書いてテストするのは簡単です。 gevent を使用するには、まず pip 経由でインストールする必要があります。

以下は gevent の使用例です:

import gevent

def task(pid):
    """
    函数中的sleep模拟阻塞一段时间,通过gevent中的异步框架进行并发。
    """
    gevent.sleep(0.5)
    print(f'Task {pid} done')

def synchronous():
    """
    任务同步执行
    """
    for i in range(1, 10):
        task(i)

def asynchronous():
    """
    任务异步执行
    """
    threads = [gevent.spawn(task, i) for i in range(10)]
    gevent.joinall(threads)

print('Synchronous:')
synchronous()

print('Asynchronous:')
asynchronous()
ログイン後にコピー

この例では、gevent フレームワークを使用して非同期コルーチンを実装します。この例を通して、非同期実行中、コルーチンの非同期特性を利用してタスクが交互に実行されることが明確にわかります。同期実行中は、タスクが 1 つずつ実行されることがわかります。

3. コルーチンの長所と短所

利点:

  1. コルーチンはデフォルトでシングルスレッドであるため、マルチスレッドの切り替えによって発生するオーバーヘッドが回避され、パフォーマンスが向上します。効率、プログラムの実行速度。
  2. コルーチンは、マルチプロセス GIL (グローバル インタープリター ロック) の問題を回避し、プログラムの効率を向上させることができます。
  3. コルーチンは無限に作成できますが、スレッドとプロセスの数は制限されています。また、コルーチンを開きすぎるとパフォーマンスの問題が発生します。

欠点:

  1. コルーチンは特殊であり、プログラマーがプログラムの実行ステータスを手動で制御する必要があり、その複雑さは比較的高く、より多くの労力が必要です。
  2. コルーチン コード自体にはエラー処理メカニズムがないため、例外の処理とコードのデバッグがより困難になります。

4. まとめ

この記事では、Pythonにおけるコルーチンの概念や実装方法、メリット・デメリットについて詳しく紹介します。コルーチンは Python の非常に重要な概念であり、非同期 IO プログラミングの基礎の 1 つです。コルーチンを通じて、同じスレッドでビジネスを同時に実行し、プログラムの実行効率を向上させ、多くのコンテキスト切り替えのオーバーヘッドを回避し、システム リソースを大幅に節約できます。ただし、コルーチンにはプログラマーに高度なプログラミングスキルが要求されることや、エラー処理メカニズムが不完全であることなどの欠点もあり、プログラマーはコルーチンを使用する際に注意する必要があります。

以上がPythonのコルーチンを詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート