非同期呼び出しとノンブロッキング呼び出しの違いは何ですか? また、ブロッキング呼び出しと同期呼び出しの間 (例を示してください)?
14 に答える
多くの場合、これらは同じものを別の名前で呼んでいますが、状況によってはまったく異なる場合もあります。だからそれは依存します。用語は、ソフトウェア業界全体で完全に一貫した方法で適用されているわけではありません。
たとえば、従来のソケット API では、非ブロッキング ソケットは、特別な「ブロックする」というエラー メッセージをすぐに返すだけのソケットですが、ブロッキング ソケットはブロックされます。またはなどの別の関数を使用して、いつ再試行するのが適切select
かpoll
を調べる必要があります。
ただし、(Windows ソケットでサポートされている) 非同期ソケット、または .NET で使用される非同期 IO パターンの方が便利です。メソッドを呼び出して操作を開始すると、完了時にフレームワークからコールバックされます。ここでも、基本的な違いがあります。非同期 Win32 ソケットは、ウィンドウ メッセージを渡すことによって結果を特定の GUI スレッドに「マーシャリング」しますが、.NET 非同期 IO はフリースレッドです (コールバックがどのスレッドで呼び出されるかはわかりません)。
そのため、常に同じ意味であるとは限りません。ソケットの例を要約すると、次のように言えます。
- ブロッキングと同期は同じことを意味します。API を呼び出すと、何らかの応答が得られるまでスレッドがハングアップし、それが返されます。
- ノンブロッキングとは、回答を迅速に返すことができない場合、APIはすぐにエラーを返し、他に何もしないことを意味します。そのため、API を呼び出す準備ができているかどうかを照会する関連する方法が必要です(つまり、効率的な方法で待機をシミュレートし、タイトなループでの手動ポーリングを回避するため)。
- 非同期とは、リクエストを満たすための「バックグラウンド」作業を開始して、APIが常にすぐに戻ることを意味するため、結果を取得するための関連する方法が必要です。
- 非同期とは、別のスレッドなど、並行して行われることを指します。
- ノンブロッキングは多くの場合、ポーリングを指します。つまり、特定の条件が満たされているかどうかを確認します (ソケットが読み取り可能であるか、デバイスにさらにデータがあるなど)。
非ブロッキング呼び出しは、使用可能なデータ(要求されたバイト数全体、それより少ないバイト数、またはまったくないデータ) とともにすぐに戻ります。
非同期呼び出しは、その全体 (全体) で実行される転送を要求しますが、将来のある時点で完了します。
この質問をJava7のNIOとNIO.2のコンテキストに置くと、非同期IOは非ブロッキングよりも1ステップ進んでいます。Java NIOノンブロッキング呼び出しでは、を呼び出すことにより、すべてのチャネル(SocketChannel、ServerSocketChannel、FileChannelなど)をそのように設定しますAbstractSelectableChannel.configureBlocking(false)
。ただし、これらのIO呼び出しが戻った後も、再度読み取り/書き込みを行うかどうか、いつ行うかなどのチェックを制御する必要があります。
たとえば、
while (!isDataEnough()) {
socketchannel.read(inputBuffer);
// do something else and then read again
}
Java 7の非同期APIを使用すると、これらのコントロールをより多様な方法で作成できます。2つの方法の1つは、を使用することCompletionHandler
です。両方のread
呼び出しが非ブロッキングであることに注意してください。
asyncsocket.read(inputBuffer, 60, TimeUnit.SECONDS /* 60 secs for timeout */,
new CompletionHandler<Integer, Object>() {
public void completed(Integer result, Object attachment) {...}
public void failed(Throwable e, Object attachment) {...}
}
}
おそらく、多数の異なる(そしてしばしば相互に排他的な)回答からわかるように、それはあなたが誰に尋ねるかによって異なります. 一部の分野では、これらの用語は同義です。または、それぞれが 2 つの類似した概念を参照している可能性があります。
- 1 つの解釈は、プログラムが制御する必要のない長いプロセスによって停止されないようにするために、呼び出しがバックグラウンドで本質的に監視されていない何かを実行するというものです。オーディオの再生がその例かもしれません。プログラムは関数を呼び出して (たとえば) mp3 を再生し、その時点から、サウンド ハードウェアでのオーディオのレンダリング プロセスの管理を OS に任せながら、他の処理を続けることができます。 .
- 別の解釈は、呼び出しはプログラムが監視する必要がある何かを行うが、プロセスの重要なポイントでプログラムに通知するだけで、ほとんどのプロセスをバックグラウンドで実行できるようにするというものです。たとえば、非同期ファイル IO がその例です。プログラムはオペレーティング システムにバッファを提供してファイルに書き込みます。OS は、操作が完了するかエラーが発生したときにのみプログラムに通知します。
どちらの場合も、遅いプロセスが完了するのを待ってプログラムがブロックされないようにすることが意図されています。実際の違いは、プログラムがどのように応答するかだけです。どの用語がどの用語を指すかは、プログラマーごと、言語ごと、プラットフォームごとに異なります。または、これらの用語がまったく異なる概念を指している場合もあります (スレッド プログラミングに関連する同期/非同期の使用など)。
申し訳ありませんが、世界的に当てはまる唯一の正解があるとは思いません。
呼び出しのブロック: 制御は、呼び出しが完了したときにのみ返されます。
ノンブロッキング呼び出し: コントロールはすぐに戻ります。その後、OS は何らかの方法で呼び出しが完了したことをプロセスに通知します。
同期プログラム:ブロッキング呼び出しを使用するプログラム。呼び出し中にフリーズしないようにするには、2 つ以上のスレッドが必要です (そのため、同期と呼ばれます - スレッドは同期的に実行されます)。
非同期プログラム:非ブロッキング呼び出しを使用するプログラム。スレッドは 1 つだけで、インタラクティブなままです。
ノンブロッキング: この関数は、スタック上で待機しません。
非同期: 呼び出しがスタックを離れた後、関数呼び出しに代わって作業を続行できます。
スペルのみが異なります。それらが参照するものに違いはありません。技術的に言えば、それらは重点が異なると言えます。非ブロッキングとは、制御フローを指します (ブロックしません。) 非同期とは、イベント\データが処理されるタイミングを指します (同期的ではありません)。
ブロッキング:プリミティブ (同期または非同期) の処理が完了した後、プロセスの呼び出しに制御が戻ります。
ノンブロッキング:呼び出し直後に制御がプロセスに戻る