[解決済み] asyncioとtrioの決定的な違いは何ですか?
質問
今日、私は
トリオ
という名前のライブラリを見つけました。この言葉は
requests
'. として
requests
は本当に良いライブラリなので、 私は
trio
.
それに関する記事はあまりなく、ただひたすら見つけた
記事
議論中
curio
と
asyncio
. 驚いたことに
trio
よりもさらに優れていると言っています。
curio
(次世代キュリオ)です。
記事の半分を読んでも、これら2つの非同期フレームワークの核心的な違いがわかりません。それはただ、いくつかの例を示しているだけです。
curio
の実装の方が
asyncio
's. しかし、基本的な構造はほとんど同じです。
ということを受け入れなければならない理由を誰か教えてください。
trio
または
curio
よりも
asyncio
? または、なぜ
trio
ではなく、組み込みの
asyncio
?
どのように解決するのですか?
どこから来たのか 私は trio の主要な作者です。また、私は curio のトップ貢献者の一人であり (あなたがリンクした記事を書きました)、asyncio を改善する方法についての議論に深く関与してきた Python コア開発者でもあります。
trio (とcurio)では、中心的な設計原則の1つは、決してコールバックでプログラムしないということです。フードを開けて、それらが内部でどのように実装されているかを見れば、コールバックを使用する場所や、目を凝らせばコールバックと同等のものがあるのでしょう。でもそれは、PythonのインタープリタがCで実装されているから、PythonとCは同等だと言っているようなものです。 あなたは は決してコールバックを使いません。
とにかく
Trioとasyncioの比較
Asyncioの方が成熟している
最初の大きな違いは、エコシステムの成熟度です。私がこれを書いている時点では 2018年3月 があり、そこには が多い asyncioをサポートするライブラリはtrioをサポートするライブラリより多くあります。例えば、今現在、trio をサポートした本当の HTTP サーバーはありません。そのため フレームワーク :: PyPI上のAsyncIOクラシファイア には現在 122 個のライブラリが含まれています。 フレームワーク :: Trio クラス分類器 は8つしか持っていません。私は、この部分の回答がすぐに古くなることを期待しています - たとえば の次のバージョンで trio サポートを追加する実験をしている Kenneth Reitz があります。 - が、今のところ、もしあなたが複雑なもののために trio を使っているなら、pypi からライブラリを取得する代わりに自分で埋めなければならないような、足りない部分に出くわすか、または、あなたが trio プログラムで asyncio ライブラリを使うための trio-asyncio パッケージ . (その trio チャットチャンネル は、利用可能なものや他の人が取り組んでいることを知るのに便利です)。
Trio はあなたのコードをよりシンプルにします
実際のライブラリの面でも、両者は大きく異なっています。trio の主な主張は、asyncio を使用するよりも同時実行コードをずっとずっとシンプルに書くことができるというものです。もちろん、自分のライブラリが物事を難しくしていると誰かが言うのを最後に聞いたのはいつでしたか...具体例を挙げましょう。例えば このトーク ( スライド ) を実装する例を使っています。 RFC 8305 "Happy eyeballs" これは、ネットワーク接続を効率的に確立するために使用される単純な並列アルゴリズムです。これは グリフ が何年も考えてきたことであり、Twistedのための彼の最新バージョンは〜600行の長さです。(Asyncioも同じぐらいでしょう。Twistedとasyncioはアーキテクチャ的にとても似ています)。講演では、trioを使ってそれを40行で実装するために必要なことをすべて教えます(そして、その間に彼のバージョンのバグも修正します)。この例では、trio を使うことで、文字通りコードが一桁簡単になるのです。
細かいところでいろいろと違いがあります
なぜこのようなことが起こるのでしょうか?それはもっと長い答えになります :-)。ブログの記事や講演でさまざまな部分を書き上げることに徐々に取り組んでいるので、利用可能になったら、この回答のリンクを忘れずに更新するようにします。基本的には、Trioは慎重に設計されたプリミティブの小さなセットを持っており、私が知っている他のライブラリとは根本的に異なる点がいくつかあります(もちろん、多くの場所のアイデアを基に構築されていますが)。以下は、いくつかのアイデアを提供するためのランダムなメモです。
asyncioとその関連ライブラリで非常に一般的な問題は、あなたが
some_function()
を呼び出すと、それが返ってくるので、終わったと思うかもしれませんが、実はまだバックグラウンドで動いているのです。これはあらゆる種類の厄介なバグにつながります。なぜなら、物事が起こる順番をコントロールするのが難しくなり、何かが実際に終わったときを知ることができなくなるからです。また、バックグラウンドタスクが処理されない例外でクラッシュすると、asyncioは通常コンソールに何かを出力して処理を継続するため、問題を直接隠してしまうことがあります。Trio では、"nurseries" を介してタスクの生成を処理する方法は、これらのことが起こらないことを意味します:関数が戻ったとき、それが完了したことを知ることができ、Trio は現在 Python の唯一の並行処理ライブラリで例外はキャッチするまで常に伝搬します。
Trioのタイムアウトとキャンセルの管理方法は斬新で、C#やGolangのような以前の最先端のシステムより優れていると思います。 実はこれについては、まるまる一冊エッセイを書きました。 を書いたので、ここではその詳細には触れません。しかし、asyncioのキャンセルシステム(というか、本当はシステムなのですが、微妙に異なるセマンティクスを持つ2つのシステムがあります)は、C#やGolangよりも古い考えに基づいていて、正しく使うのが難しいのです。(たとえば、バックグラウンド タスクを生成することによって、コードが誤ってキャンセルを "escape" することは簡単です; 前項を参照)。
膨大な数の冗長な スタッフ があり、asyncioでは を使うとき、どれを使えばいいのかわからなくなることがあります。 . futures、task、coroutineがあり、これらは基本的に同じ目的で使用されますが、それぞれの違いを知っておく必要があります。ネットワークプロトコルを実装したい場合、プロトコル/トランスポート層とストリーム層のどちらを使うか選ばなければなりませんが、どちらも厄介な落とし穴があります(これは、冒頭の の最初の部分は、あなたがリンクしたエッセイ の最初の部分がそれです)。
Trioは現在、control-Cが期待通りに動作する唯一のPython用並行処理ライブラリです。
KeyboardInterrupt
を発生させます)。これは小さなことですが、大きな違いです :-)。様々な理由から、私はこれがasyncioで修正可能であるとは思いません。
まとめ
もしあなたが来週本番環境に何かを出荷する必要があるなら、asyncio (またはTwisted、Tornado、gevent、これらはさらに成熟しています) を使うべきでしょう。これらは大規模なエコシステムがあり、他の人々はあなたより先に実運用でそれらを使用しており、どこにも行くことはないでしょう。
もしこれらのフレームワークを使おうとして挫折したり混乱したりするならば、あるいは物事を行う異なる方法を試したいならば、間違いなくtrioをチェックしてください - 私たちはフレンドリーです :-)。
もしあなたが今から1年後に何かを製品として出荷したいのであれば...私はあなたに何を伝えるべきかわかりません。Pythonの並行処理は流動的です。Trioは設計レベルでは多くの利点がありますが、それはasyncioの先発に打ち勝つのに十分でしょうか?asyncioが標準ライブラリにあることは利点になるのか、それとも欠点になるのか?(最近、誰もが
requests
を使っていることに注目してください。
urllib
.) trioの新しいアイデアのうち、いくつがasyncioに追加できるでしょうか?誰も知りません。今年のPyConでは、このことについて多くの興味深い議論が行われると期待しています :-)。
関連
-
[解決済み] staticmethodとclassmethodの違いについて
-
[解決済み] Pythonのリストメソッドであるappendとextendの違いは何ですか?
-
[解決済み] 最小限の驚き」と「変更可能なデフォルトの引数
-
[解決済み] パラメータに**(ダブルスター/アスタリスク)、*(スター/アスタリスク)がありますが、これはどういう意味ですか?
-
[解決済み】__str__と__repr__の違いは何ですか?
-
[解決済み】venv, pyvenv, pyenv, virtualenv, virtualenvwrapper, pipenvなどの違いは何ですか?
-
[解決済み】type()とisinstance()の違いは何ですか?)
-
[解決済み】Djangoでnull=Trueとblank=Trueの違いは何ですか?
-
[解決済み] 2つの線分が交差しているかどうかを確認するにはどうすればよいですか?
-
[解決済み] Pythonでマルチプロセッシングキューを使うには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Pythonの構文に新しいステートメントを追加することはできますか?
-
[解決済み] googletransがエラー 'NoneType' オブジェクトに 'group' 属性がない、と言って動かなくなった。
-
[解決済み] Pythonの要素別タプル演算(sumなど
-
[解決済み] Django Rest Framework ファイルアップロード
-
[解決済み] python-requests モジュールからのすべてのリクエストをログに記録します。
-
[解決済み] 古いバージョンのPythonにおける辞書のキーの並び順
-
[解決済み] Jupyter (IPython)ノートブックのセッションをpickleして保存する方法
-
[解決済み] Cythonのコードを含むPythonパッケージはどのように構成すればよいのでしょうか?
-
[解決済み] Flask でグローバル変数はスレッドセーフか?リクエスト間でデータを共有するには?
-
[解決済み] Python 言語を決定するには?