非同期プログラミングは、単なる別のプログラミングトリックというよりも哲学です。あなたの最後の質問は主にプログラミングの側面についての答えを集めましたが、私の答えはほとんど理論的であるための孤立した孤独でしたが、参照だけでなく説明と同じ行に基づいて新鮮な視点を提供しようとしています。
これは、非同期プログラミングの理由と方法の基本についてです。
ベーカリーショップに行くとしましょう(注文後にケーキが準備されると仮定します)-2つの選択肢があります。ケーキの準備ができるまで待つか、注文して家に帰って迎えに行くかを選択します。準備ができたら後で。最初のメソッド(待機)は同期メソッドで、後のメソッドは非同期メソッドです。言うまでもなく、この例は、同期ではなく非同期メソッドを使用する必要がある理由を示しています。
イベントベースのプログラミングは、非同期システムを構築する方法の1つにすぎず、有用な設計パターンではなく、アーキテクチャパターンです。この理論が実際に有用な方法で使用されているケースをリストアップしています-それがいくらかの明確さをもたらすことを望んでいます
非同期システムの最初の例の1つは、UnixシステムIOです。私たちが知っている間read()
、write()
さらにはselect()
呼び出すブロックをプログラムの流れが、OSの内部で、彼らは非同期である、すなわち、カーネルは、一般的に、このような時間のCPUがフリーになるまでブロックデバイス(別名ハードディスク)は、バッファを満たすためにいくつかの時間がかかるだろうことを知っていますそのそれぞれのスレッドから、スレッドは(準備ができていない)としてパークされます。参照1. Moris Bach「Unixオペレーティングシステムの設計」
別の最も一般的な例は、UIフレームワークの大部分です。ここでは、すべてのユーザークリックが最初にコントローラーを介してディスパッチされ、コントローラーはそれぞれのアプリケーションをコールバックします。重要なことは、そのようなコールバックはコールバックを待たせてはならないことです。UIコントローラーからバックエンドへのコールバックは、重い処理を伴う場合、通常非同期です。
(純粋なデザインパターンとしての)非同期プログラミングのもう1つの良い例は、アクティブオブジェクトです。アクティブなオブジェクトとは、多くのリクエストをキューに保持し、1つずつ実行できるように、独自のプライベートスレッドを持つオブジェクトです。このペーパー:Active Objectを参照してください。このパターンは、エンタープライズソフトウェアからモバイルフレームワークまで多用されています。人気のあるプラットフォームJava / EJBおよび.NETでは、通常は通常のオブジェクトをアクティブオブジェクトにすることができるローカルまたはリモートの非同期メソッド呼び出しが可能です。アクティブオブジェクトは、Symbianに存在していました。AapoHaapanenによるSymbian OSのアクティブオブジェクト(これも参照:Symbianのアクティブオブジェクト)。これは現在もAndroid)。
アクティブオブジェクトとは別に、同じ著者のDouglas C. Schmidtは、アクティブオブジェクトと他の類似点であり、非同期パターンでもある他の多くの作品を生み出しています。このイベント処理パターンを参照してください。完全なアカウントは、彼の著書「パターン指向ソフトウェアアーキテクチャ:並行オブジェクトとネットワークオブジェクトのパターン-V2」で入手できます。
指定されたオブジェクトのニーズは、APIを返すようにするとしながら、実際に作業を遂行するために、バックグラウンドで作業し、通常の方法論は、これを達成するためにマルチスレッドシステムを持つことです。スレッドシステムは、C(posix)、C ++(boost)からJava、C#などに至る所に存在します。アクティブオブジェクトは本質的にこれを隠すことができる抽象化にすぎません。アクティブオブジェクトの実装がネイキッドスレッドよりも望ましい理由をご覧ください。別の良い読書。
ただし、この概念は、アプリケーション内のスレッドやオブジェクトを超えて非同期になります。最適な使用法の1つは、2つのアプリケーションが調整のために互いに待つ必要がない分散システムでの使用です。古き良き(または見た目が良くない)RPCは同期的でした。[もちろん、他の非同期RPCもあります]。しかし、メッセージ指向ミドルウェアのような最新の代替手段は、正当な理由で真に非同期です。
最後になりますが、最も興味深いのは、非同期通信モデルの恩恵を受けることができるエージェントプログラミングです。
非同期プログラミングはセクシーに見えますが、次のような独自の複雑さを生み出します。
- 戻り値を渡すためのフレームワーク
- 通信の追加オーバーヘッド
- コンストラクトを同期するための追加の必要性
- 物事が正しく行われない場合、デッドロック、レースなどの可能性。
... 等々。
常に真の目的でのみ使用する必要があります。
それでは、いつ非同期モデルを使用すべきでしょうか?バックグラウンドスレッドをいつ配置し、呼び出し元が非同期になるのを許可する必要がありますか?
システムが厳密で深刻なリソース会話を適用する場合:たとえば、スレッドの絶対数を固定したい場合。非同期パターンは、システムにキューの実装を強制します。
発信者が「他に役立つ有用なこと」を行う必要がある場合は、まさに本物です。非常に多くの場合、他のスレッドはブロックを解除しても、何も役に立たず、結果のポーリングを回避します。実際、これは基本的な同期モデルよりも多くのCPUを消費する可能性があります。
分散システムでより高いレベルの信頼性が必要な場合。(メッセージ指向ミドルウェアを参照)。