StacklessPythonに関連する多くの質問があります。しかし、これに私の質問に答える人はいないと思います(間違っている場合は訂正してください-お願いします!)。いつも話題になっているので知りたいです。 Stacklessは何に使用しますか? CPythonよりも優れていますか?
はい、グリーンスレッド(スタックレス)があり、操作がブロックされていない限り、多くの軽量スレッドをすばやく作成できます(Rubyのスレッドのようなものですか?)。これは何に最適ですか? CPythonで使用したい他の機能は何ですか?
これにより、大量の並行性を処理できます。正気の人は10万のシステムスレッドを作成しませんが、スタックレスを使用してこれを行うことができます。
この記事では、それをテストし、PythonとGoogleGo(新しいプログラミング言語)の両方で10万のタスクレットを作成します。 http://dalkescientific.com/writings/diary/ archive/2009/11/15/100000_tasklets.html
驚いたことに、Google Goがネイティブコードにコンパイルされていて、コルーチンの実装を宣伝している場合でも、Pythonが勝ちます。
Stacklessは、入力データに応じて非常に多くのレデューサーを使用できるmap/reduceアルゴリズムの実装に適しています。
Stackless Pythonの主な利点は、非常に軽量なコルーチンのサポートです。 CPythonはコルーチンをネイティブにサポートしていません(コメントにジェネレーターベースのハックを投稿する人がいると思いますが)。したがって、コルーチンの恩恵を受ける問題がある場合、StacklessはCPythonの明らかな改善です。
プログラム内で多数の同時タスクを実行している場合にExcelが使用される主な領域だと思います。例としては、AIのループスクリプトを実行するゲームエンティティや、作成に時間がかかるページで多くのクライアントにサービスを提供しているWebサーバーなどがあります。
ただし、共有データに関しては、同時実行の正確性に関する一般的な問題の多くがまだありますが、決定論的なタスク切り替えにより、制御が転送される場所が正確にわかっているため、共有状態が必要な正確なポイントがわかっているため、安全なコードを簡単に記述できます。最新の。
Thirlerは、EveOnlineでスタックレスが使用されたことをすでに述べています。それを念頭に置いて:
(..)スタックレスは、タスクをより小さなタスクであるタスクレットに分割できるようにすることで、これにさらにひねりを加えます。タスクレットは、メインプログラムから分割して独自に実行できます。これは、電子メールの送信やイベントのディスパッチなどのファイアアンドフォーゲットタスク、またはネットワークパケットの送受信などのIO操作)に使用できます。1つのタスクレットがパケットを待機します。他の人がゲームループを実行し続けている間、ネットワークから。
ある意味ではスレッドに似ていますが、プリエンプティブではなく、明示的にスケジュールされているため、同期に関する問題は少なくなります。また、タスクレット間の切り替えはスレッドの切り替えよりもはるかに高速であり、アクティブなタスクレットを多数持つことができますが、スレッドの数はコンピューターのハードウェアによって厳しく制限されます。
(この引用は ここ から得ました)
PyCon 2009では、 非常に興味深い講演 が行われ、CCPGamesでStacklessが使用される理由と方法が説明されました。
また、非常に優れた 紹介資料 があります。これは、スタックレスがアプリケーションに適したソリューションである理由を説明しています。 (少し古いかもしれませんが、読む価値があると思います)。
EVEOnlineは主にStacklessPythonでプログラムされています。彼らはそれの使用に関するいくつかの開発ブログを持っています。ハイパフォーマンスコンピューティングに非常に役立つようです。
Stackless自体は使用していませんが、並行性の高いネットワークアプリケーションを実装するためにGreenletを使用しました。 Linden Labが採用したユースケースには、高性能のスマートプロキシ、膨大な数のマシンにコマンドを分散するための高速システム、大量のデータベースの書き込みと読み取りを行うアプリケーション(約1の比率)があります。 :2、これは非常に書き込みが多いため、データベースが戻るのを待つためにほとんどの時間を費やしています)、および内部Webデータ用のWebクローラータイプのもの。基本的に、多くのネットワークI/Oを実行する必要があると予想されるアプリは、何億もの軽量スレッドを作成できるというメリットがあります。 10,000の接続されたクライアントは、私には大したことではないようです。
ただし、StacklessやGreenletは完全なソリューションではありません。それらは非常に低レベルであり、それらを最大限に使用するアプリケーションを構築するには、多くのモンキーワークを行う必要があります。 Greenletの上にネットワークとスケジューリングのレイヤーを提供するライブラリを維持しているため、特にアプリの作成が非常に簡単であるため、これを知っています。現在、これらはたくさんあります。私はEventletを管理していますが、Concurrence、Chiral、そしておそらく私が知らない他のいくつかもあります。
書きたいアプリの種類が私が書いたもののように聞こえる場合は、これらのライブラリの1つを検討してください。 StacklessとGreenletのどちらを選択するかは、やりたいことのニーズに最適なライブラリを決定することほど重要ではありません。
私の見方では、グリーンスレッドの基本的な有用性は、高遅延操作を実行するオブジェクトが大量にあるシステムを実装することです。具体的な例は、他のマシンとの通信です。
_def Run():
# Do stuff
request_information() # This call might block
# Proceed doing more stuff
_
スレッドを使用すると、上記のコードを自然に記述できますが、オブジェクトの数が十分に多い場合、スレッドは適切に実行できません。しかし、本当に大量の場合でもグリーンスレッドを使用できます。上記のrequest_information()
は、他の作業が待機しているスケジューラに切り替えて、後で戻る可能性があります。スレッドを使用せずに「ブロッキング」関数を呼び出すことができるというすべての利点がありますすぐに戻るかのように。
これは、コードを簡単な方法で記述したい場合、あらゆる種類の分散コンピューティングに明らかに非常に役立ちます。
複数のコアがロックの待機を軽減することも興味深いです。
_def Run():
# Do some calculations
green_lock(the_foo)
# Do some more calculations
_
_green_lock
_関数は基本的にロックを取得しようとし、オブジェクトを使用している他のコアが原因で失敗した場合は、メインスケジューラに切り替えます。
繰り返しになりますが、グリーンスレッドはブロッキングを軽減するために使用されており、コードを自然に記述し、それでも良好に機能することを可能にします。