Python グリーンレットの使用法とその実装原理の分析の紹介

高洛峰
リリース: 2017-03-23 15:55:23
オリジナル
1080 人が閲覧しました

最近、マルチスレッド、マルチプロセス、コルーチンなど、Pythonの並列開発技術を勉強し始めました。インターネット上の情報を少しずつ整理していき、今日はgreenlet関連の情報を整理しました。

同時処理の技術的背景

多くの場合、特にマルチコアとマルチプロセッサの時代では、並列コンピューティングによってシステムのスループットが大幅に向上するため、並列処理は現在非常に重要です。 lisp のように人々はそれを再び取り上げるようになり、関数型プログラミングはますます人気が高まっています。 Pythonで並列処理を行うためのライブラリ「greenlet」を紹介します。 Pythonにはスタックレスと呼ばれる非常に有名なライブラリがあり、これは主にタスクレットと呼ばれるマイクロスレッドを使用します。グリーンレットとスタックレスの最大の違いは、非常に軽量であることです。十分ではありません。グリーンレットではスレッドの切り替えを自分で処理する必要があるということです。つまり、どのグリーンレットを今実行するか、どのグリーンレットを再度実行するかを指定する必要があります。

greenletの実装仕組み

従来、Webプログラムの開発にはPythonが使用されており、リクエスト処理のために各プロセスで複数のスレッドが起動されていました。リクエストは特に短いことを保証する必要があります。そうでない場合、リクエストが遅すぎるとサーバーはサービスを拒否します。通常、サービスはオンラインになるときにパフォーマンスがテストされます。通常の状況ではそれほど問題はありませんが、すべてのシナリオで実行できるわけではありません。一度表示されると、ユーザーは応答せずに長時間待機することになり、後ですべてが使用できなくなります。 Python の下で Greenlet というコルーチンに変換されたので、その実装メカニズムを簡単に理解できました。

皆さん Greenlet はヒープ内にある単なる Python オブジェクト (PyGreenlet) なので、何百万、あるいは数十個作成しても問題ありません。

typedef struct _greenlet {
	PyObject_HEAD
	char* stack_start;
	char* stack_stop;
	char* stack_copy;
	intptr_t stack_saved;
	struct _greenlet* stack_prev;
	struct _greenlet* parent;
	PyObject* run_info;
	struct _frame* top_frame;
	int recursion_depth;
	PyObject* weakreflist;
	PyObject* exc_type;
	PyObject* exc_value;
	PyObject* exc_traceback;
	PyObject* dict;
} PyGreenlet;
ログイン後にコピー

各グリーンレットは実際には関数であり、この関数の実行時にコンテキストが保存されます。同じプロセス内のすべてのグリーンレットは、割り当てられた共通のユーザー スタックを共有します。したがって、競合しないスタック データを持つグリーンレットのみがこのグローバル スタックを同時に使用できます。グリーンレットの stack_stop とスタックの先頭を保存するためにグリーンレットが使用されます。スタック内の stack_stop と stack_start の位置をコピーできるように、保存された位置は stack_copy と stack_saved によって記録されます。そうしないと、スタック データが破壊されます。したがって、アプリケーションによって作成されたグリーンレットは、継続的にデータをヒープにコピーしたり、ヒープからスタックにコピーしたりすることで、同時実行性を実現できます。 IO タイプのアプリケーションにコルーチンを使用するには

以下は、greenlet の単純なスタック スペース モデルです (greenlet.c より)

A PyGreenlet is a range of C stack addresses that must be
saved and restored in such a way that the full range of the
stack contains valid data when we switch to it.

Stack layout for a greenlet:

               |     ^^^       |
               |  older data   |
               |               |
  stack_stop . |_______________|
        .      |               |
        .      | greenlet data |
        .      |   in stack    |
        .    * |_______________| . .  _____________  stack_copy + stack_saved
        .      |               |     |             |
        .      |     data      |     |greenlet data|
        .      |   unrelated   |     |    saved    |
        .      |      to       |     |   in heap   |
 stack_start . |     this      | . . |_____________| stack_copy
               |   greenlet    |
               |               |
               |  newer data   |
               |     vvv       |
ログイン後にコピー

以下は、単純な greenlet コードです。プログラミング言語。現在、私が知っているコルーチン サポートを提供する言語には、Python、lua、go、erlang、scala、rust があります。コルーチンとスレッドの違いは、コルーチンはオペレーティング システムによって切り替えられるのではなく、

プログラマー

コーディングによって切り替えられるということです。つまり、切り替えはプログラマーによって制御されるため、スレッドにはいわゆるセキュリティの問題はありません。 すべてのコルーチンはプロセス全体のコンテキストを共有するため、コルーチン間の交換も非常に便利です。

2 番目のソリューション (I/O 多重化) と比較すると、コルーチンを使用して作成されたプログラムは、完全なプロセスを複数のマネージド イベント ハンドラーに分割するのではなく、より直感的になります。コルーチンの欠点はマルチコアを利用できないことかもしれませんが、これはコルーチン + プロセスで解決できます。

コルーチンは、同時実行性を処理してパフォーマンスを向上させるために使用できます。また、ステート マシンを実装してプログラミングを簡素化するために使用することもできます。 2本目をさらに使います。私は昨年末に Python に出会い、Python のコルーチンの概念を知りました。その後、Greenlet もコルーチン ソリューションの 1 つであり、Python のコルーチンの概念を知りました。特にステートマシンの処理に使用できるソリューション。

現時点ではこの部分はほぼ完成していますので、後ほどまとめさせていただきます。

まとめると:

1) マルチプロセスはマルチコアの利点を活かすことができますが、プロセス間の通信が面倒であり、また、プロセス数の増加によりパフォーマンスの低下が発生し、プロセス切り替えのコストが高くなります。 。プログラム フローの複雑さは I/O 多重化よりも低くなります。

2) I/O多重化とは、プロセス内で複数の論理的なプロセスをプロセスを切り替えることなく処理することで、パフォーマンスが高く、プロセス間での情報共有が容易です。しかし、マルチコアの利点を活かすことができず、また、プログラムの流れがイベント処理によって細分化され、プログラムが複雑になり、わかりにくくなります。

3) スレッドはプロセス内で実行され、オペレーティング システムによってスケジュールされるため、スイッチング コストが低くなります。また、プロセスの仮想アドレス空間を共有するため、スレッド間での情報の共有が簡単になります。ただし、スレッドの安全性の問題により、スレッドの学習曲線が急峻になり、エラーが発生しやすくなります。

4) コルーチンはプログラミング言語によって提供され、プログラマーの制御下で切り替えられるため、スレッドの安全性の問題はなく、ステートマシン、同時リクエストなどの処理に使用できます。ただし、マルチコアを活用することはできません。

上記の 4 つのソリューションは一緒に使用できます。私はプロセス + コルーチン モデルについてより楽観的です

以上がPython グリーンレットの使用法とその実装原理の分析の紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!