web-dev-qa-db-ja.com

非同期プログラミングを学ぶ

非同期の非ブロッキングイベント駆動型プログラミングが大流行しているようです。私はこれが何を意味するのかについての基本的な概念的な理解を持っています。ただし、コードが非同期であることからいつどこでメリットが得られるか、またはブロックIOを非ブロックにする方法がわからない。ライブラリを使用してこれを実行できると確信していますが、より詳細な概念と、自分で実装するためのさまざまな方法の方が興味を持っています。

この主題に関する包括的な/決定的な本、またはその他のリソースはありますか(例: GoF for Design Patterns、 K&R for C、 tldp for things) bashのように)?

(注:これが実際に機能的に私の質問と同じ質問であるかどうかはわかりません 学習イベント駆動型プログラミング

20
xenoterracide

非同期プログラミングは、単なる別のプログラミングトリックよりもはるかに哲学です。あなたの最後の question は主にプログラミングの側面についての回答を引き付けましたが、私の answer はほとんど理論的であるので切り離された孤独でしたが、私はあなたに同じ上に構築する新鮮な視点を与えようとしています行ではなく、単なる参照ではなく説明。

これは、非同期プログラミングの理由と方法の基本についてです。

ベーカリーショップに行ったとしましょう(注文後にケーキが準備されると仮定します)-2つの選択肢があり、どちらかをwaitまで待つケーキの準備ができているか、注文を出し、家に戻って準備ができたら後で受け取ります。最初の(待機)は同期メソッドで、それ以降は非同期メソッド。言うまでもなく、この例は、同期メソッドではなく非同期メソッドを使用する必要がある理由を示しています。

イベントベースのプログラミングは、非同期システムを構築する方法の1つにすぎず、単なる有用な設計パターンではなく、アーキテクチャパターンです。この理論が実際に役立つ方法で使用されているケースをリストアップしています-ある程度明確になることを期待しています

  1. 非同期システムの最初の例の1つは、UnixシステムIOです。 read()write()、さらにselect()を知っている間は、プログラムフローblocksを呼び出します、ただしOS内では非同期です。つまり、カーネルは通常、ブロックデバイス(別名ハードディスク)がバッファを満たすまでにしばらく時間がかかることを知っています。このような時間になると、CPUはそれぞれのスレッドから解放され、スレッドは次のようにパークされます。 (準備ができていない)。参照 1。Moris Bach "The design of Unix Operating system"

  2. もう1つの最も一般的な例は、UIフレームワークの大部分です。ここでは、すべてのユーザークリックが最初にコントローラーを介してディスパッチされ、コントローラーがそれぞれのアプリケーションをコールバックします。重要なことは、そのようなコールバックはコールバックを待たせてはならず、そうでなければシステムがフリーズします。 UIコントローラーからバックエンドへのコールバックは、重い処理を伴う場合、通常は非同期です。

  3. (純粋な設計パターンとしての)非同期プログラミングのもう1つの良い例は、アクティブオブジェクトです。アクティブなオブジェクトとは、ownプライベートスレッドを持ち、多くのリクエストをキューに保持して1つずつ実行できるオブジェクトです。このペーパーを参照してください: Active Object 。このパターンは、エンタープライズソフトウェアからモバイルフレームワークに至るまで、頻繁に使用されています。一般的なプラットフォーム Java/EJB および.NETはローカルまたはリモートを許可します 非同期メソッドの呼び出し これにより、通常のオブジェクトをアクティブオブジェクトにすることができます。アクティブオブジェクトはSymbianに存在していました: Symbian OSのアクティブオブジェクトby Aapo Haapanen (これも参照してください: Symbianのアクティブオブジェクト )。これは Android )にも存在します。

  4. Activeオブジェクトとは別に、同じ著者 Douglas C. Schmidt は、Activeオブジェクトの他の類似物であり、非同期パターンでもある他の多くの作品を生み出しています。これを参照してください イベント処理パターン そして完全なアカウントは彼の本で利用可能です パターン指向ソフトウェアアーキテクチャ:並行オブジェクトとネットワークオブジェクトのパターン-V2

  5. 特定のオブジェクトがAPIを返す必要がある場合、while実際に作業を実行するためにバックグラウンドで動作し、通常の方法はマルチスレッドシステムを使用することですこれを達成するために。スレッドシステムは、C(posix)、C++( boost )からJava、C#など、至る所に存在します。 Active Objectは基本的に、これを隠すことができる単なる抽象化です。 why を参照してください。アクティブなオブジェクトの実装は、ネイキッドスレッドよりも望ましいです。別の 良い読み

  6. ただし、この概念は、アプリケーション内のスレッドやオブジェクトを超えて非同期になります。最適な使用法の1つは、2つのアプリケーションが調整を相互に待機する必要がない分散システムでの使用です。古き良き(あなたがそれを見るいずれの方法でもそれほど良くない) [〜#〜] rpc [〜#〜] は同期的でした。 [もちろん、他にも 非同期RPC があります]。しかし、 Message Oriented Middleware のような最新の代替手段は、正当な理由により完全に非同期です。

  7. 最後ですが、最も興味深いものは エージェントプログラミング で、これは 非同期通信モデル から利益を得ることができます。


非同期プログラミングはsexyに見えますが、次のような独自の複雑さが生じます。

  • 戻り値を渡すためのフレームワーク
  • 通信の追加オーバーヘッド
  • 同期構造の追加の必要性
  • 物事が正しく行われない場合、デッドロック、レースなどの可能性。

... 等々。

常に本物の理由でのみ使用する必要があります。

では、いつ非同期モデルを使用すればよいですか?バックグラウンドスレッドを配置して、呼び出し元が非同期になるのを許可する必要があるのはいつですか?

  1. システムが厳密なリソース会話を厳密に適用する必要がある場合:たとえば、絶対的な固定数のスレッドを保持する必要があります。非同期パターンは、システムに強制的にキューを実装させます。

  2. 発信者が行う必要がある場合「その他の役立つこと」は、本当に本物です。多くの場合、他のスレッドは、ブロックを解除しても、有用なことは何もせず、結果のポーリングを停止します。これは確かに、基本的な同期モデルよりも多くのCPUを消費する可能性があります。

  3. 分散システムでより高いレベルの信頼性が必要な場合。 ( Message Oriented Middleware を参照してください)。

36
Dipan Mehta