非同期実行と同期実行の違いは何ですか?
非同期実行と同期実行の違いは何ですか?
回答:
同期的に何かを実行するとき、それが完了するのを待ってから別のタスクに移ります。非同期で何かを実行する場合、完了する前に別のタスクに進むことができます。
そうは言っても、コンピューターのコンテキストでは、これは別の「スレッド」でプロセスまたはタスクを実行することを意味します。スレッドは、作業単位として存在する一連のコマンド(コードのブロック)です。オペレーティングシステムは、複数のスレッドを管理し、別のスレッドに切り替えて処理を行う前に、スレッドにプロセッサ時間の断片( "スライス")を割り当てることができます。コアは(しゃれを許して)、プロセッサはコマンドを実行するだけでよく、一度に2つのことを実行するという概念はありません。オペレーティングシステムは、時間のスライスを異なるスレッドに割り当てることでこれをシミュレートします。
ここで、複数のコア/プロセッサを組み合わせて導入すると、実際に同時に発生する可能性があります。オペレーティングシステムは、最初のプロセッサの1つのスレッドに時間を割り当ててから、同じ時間ブロックを別のプロセッサの別のスレッドに割り当てることができます。これはすべて、オペレーティングシステムがタスクの完了を管理できるようにすることに関するものであり、コードを続行して他のことを行うことができます。
非同期プログラミングは、同時に実行できるときに物事がどのように結び付くかというセマンティクスのため、複雑なトピックです。このテーマに関する記事や本は数多くあります。見てください!
同期/非同期はマルチスレッドで何もする必要がありません。
同期または同期とは、何らかの方法で「接続」または「依存」することを意味します。つまり、2つの同期タスクは相互に認識している必要があり、1つのタスクは、他のタスクが完了するまで開始を待機するなど、他のタスクに依存する何らかの方法で実行する必要があります。
非同期とは、それらが完全に独立していることを意味し、どちらの方法でも、開始時または実行時に、どちらも他方を考慮してはなりません。
同期(1スレッド):
1 thread -> |<---A---->||<----B---------->||<------C----->|
同期(マルチスレッド):
thread A -> |<---A---->|
\
thread B ------------> ->|<----B---------->|
\
thread C ----------------------------------> ->|<------C----->|
非同期(1スレッド):
A-Start ------------------------------------------ A-End
| B-Start -----------------------------------------|--- B-End
| | C-Start ------------------- C-End | |
| | | | | |
V V V V V V
1 thread->|<-A-|<--B---|<-C-|-A-|-C-|--A--|-B-|--C-->|---A---->|--B-->|
非同期(マルチスレッド):
thread A -> |<---A---->|
thread B -----> |<----B---------->|
thread C ---------> |<------C--------->|
<
、>
文字で表されるタスクA、B、Cの開始点と終了点。|
技術的には、同期/非同期の概念は、実際にはスレッドとは何の関係もありません。一般に、同じスレッドで実行されている非同期タスクを見つけるのは珍しいことですが、可能であり(例については以下を参照)、別々のスレッドで同期して実行されている2つ以上のタスクを見つけることは一般的です...いいえ、コンセプト同期/非同期の関係しているだけに、他の(最初の)タスクが完了した、またはそれを待たなければならないかどうかを前に、第2または後続タスクが開始されることができるかどうかと。以上です。タスクが実行されるスレッド(1つまたは複数)、またはプロセス、CPU、または実際にはどのハードウェアかは関係ありません。実際、この点を明確にするために、グラフィックを編集してこれを示しています。
非同期の例:
多くのエンジニアリング問題を解決するために、ソフトウェアは問題全体を複数の個別のタスクに分割し、それらを非同期で実行するように設計されています。行列の反転、または有限要素解析の問題は、良い例です。コンピューティングでは、リストのソートがその例です。たとえば、クイックソートルーチンは、リストを2つのリストに分割し、それぞれに対してクイックソートを実行し、それ自体(クイックソート)を再帰的に呼び出します。上記の例の両方で、2つのタスクは非同期で実行できます(多くの場合)。それらは別々のスレッド上にある必要はありません。CPUが1つで実行スレッドが1つしかないマシンでも、最初のタスクが完了する前に2番目のタスクの処理を開始するようにコーディングできます。唯一の基準は、1つのタスクの結果が他のタスクへの入力として必要ないことです。。タスクの開始時刻と終了時刻が重複している限り(どちらの出力も他方への入力として必要でない場合のみ可能)、使用中のスレッドの数に関係なく、非同期で実行されます。
同期の例:
タスクを順番に実行する必要があるが、別のマシンで実行する必要がある複数のタスクで構成されるプロセス(データのフェッチや更新、金融サービスからの株価情報の取得など)。別のマシンにある場合は、同期か非同期かにかかわらず、別のスレッドにあります。
簡単に言えば:
同期
映画のチケットを取得するためのキューにいます。あなたの前の全員が1つを取得するまで、1つを取得することはできません。同じことが、あなたの後ろに並んでいる人々にも当てはまります。
非同期
あなたは他の多くの人々と一緒にレストランにいます。あなたはあなたの食べ物を注文します。他の人も食べ物を注文できます。注文する前に、食べ物が調理されて出されるのを待つ必要はありません。キッチンレストランでは、労働者が調理、料理、注文を続けています。調理するとすぐに料理が出されます。
同期実行
私の上司は忙しい人です。彼は私にコードを書くように言った。私は彼に言います:元気です。私は始めました、そして彼はハゲワシのように私を見ていて、私の後ろに立って、私の肩から離れています。私は「おい、WTF:これを終えている間に、なぜあなたは行って何かしませんか?」のようです。
彼は「いいえ、あなたが終わるまでここで待っています。」これは同期です。
非同期実行
ボスは私にそれをするように言って、私の仕事をすぐに待つのではなく、ボスは出かけて他の仕事をします。仕事が終わったら、上司に報告して「完了です!」と言います。これは非同期実行です。
(私のアドバイスをしてください:あなたの後ろにいる上司と一緒に仕事をしないでください。)
同期実行とは、実行が単一のシリーズで発生することを意味します。 A->B->C->D
。これらのルーチンを呼び出している場合は、A
実行、終了、B
開始、終了、C
開始などのようになります。
非同期実行、あなたはルーチンを開始し、あなたがあなたの次を開始しながら、それがバックグラウンドで実行させ、その後、いくつかの点で、「最後まで、この待ち」と言います。それはもっと似ています:
スタート A->B->C->D->
待ちのためのA
仕上げに
利点は、、、およびまたはが(バックグラウンドで別のスレッドで)実行されている間に実行できるためB
、リソースをより有効に活用して、「ハング」または「待機」を減らすことができます。C
D
A
簡単に言えば、同期とは、2つ以上のプロセスの開始点と終了点であり、実行ではありません。この例では、プロセスAのエンドポイントがプロセスBの開始ポイントと同期されています。
同期 | -------- A -------- | | -------- B -------- |
一方、非同期プロセスでは、開始プロセスとエンドポイントが同期されていません。
非同期 | -------- A -------- | | -------- B -------- |
プロセスAがプロセスBとオーバーラップしている場合、それらは並行してまたは同期して(辞書定義)実行されているため、混乱が生じます。
更新:Charles Bretanaが彼の回答を改善したため、この回答は単純な(潜在的に過度に単純化された)ニーモニックになりました。
同期とは、呼び出し側が応答または完了を待機することを意味し、非同期の場合は、呼び出し側が続行し、応答が後で来ることを意味します(該当する場合)。
例として:
static void Main(string[] args)
{
Console.WriteLine("Before call");
doSomething();
Console.WriteLine("After call");
}
private static void doSomething()
{
Console.WriteLine("In call");
}
これは常に出力されます:
Before call
In call
After call
しかし、doSomethingを非同期(複数の方法で実行)にすると、出力は次のようになります。
Before call
After call
In call
非同期呼び出しを行うメソッドは、すぐに次のコード行に進むためです。非同期操作では実行順序を保証できないため、「できた」と言います。スレッドのタイミングなどによっては、オリジナルとして実行することもできます。
これは少し回りくどい説明だと思いますが、それでも実際の例を使用して明確にします。
小さな例:
オーディオの再生に3つのステップが含まれているとします。
オーディオプレーヤーがすべての曲に対して順次ステップ1、2、3を実行する場合は、同期しています。曲が実際に取得されて解凍されるまで、曲を聞くにはしばらく待つ必要があります。
オーディオプレーヤーが互いに独立してステップ1、2、3を実行する場合、非同期です。すなわち。オーディオ1の再生中に(ステップ3)、オーディオ3をハードディスクから並行してフェッチし(ステップ1)、オーディオ2を並行して解凍した場合。(ステップ2)フェッチと解凍をあまり待たずに曲を聞くことができます。
同期および非同期操作は、現在のタスクに関連する新しいタスクの実行順序に関するものです。テーブル上の2つのタスク:現在のタスクと新しいタスク
同期(ブロッキング)-タスクが1つずつ実行されることを意味します。次のタスクは、前のタスクが終了した後にのみ開始されます。終了するTask 2
まで開始されませんTask 1
非同期(非ブロッキング)–タスクを実行するとすぐに制御が戻り、コードを実行して結果を後で通知する(コールバック、機能など)ことを約束します。終了していなくTask 2
ても実行されますTask 1
簡単に言うと、非同期実行はバックグラウンドで何かを行っています。
たとえば、インターネットからファイルをダウンロードする場合は、同期機能を使用してファイルをダウンロードできますが、ファイルのダウンロードが完了するまでスレッドがブロックされます。これにより、アプリケーションがユーザー入力に応答しなくなる可能性があります。
代わりに、非同期方式を使用してバックグラウンドでファイルをダウンロードできます。この場合、ダウンロード機能はすぐに戻り、プログラムの実行は通常どおり続行されます。すべてのダウンロード操作はバックグラウンドで実行され、プログラムが完了すると通知されます。
本当に簡単な例として、
同期
3人の生徒が道路でリレーレースを実行するように指示されたと想像してください。
1人目の生徒は指定された距離を走り、停止してバトンを2番目に渡します。誰も走り始めていません。
1------>
2.
3.
2人目の生徒がバトンを取得すると、指定された距離を走り始めます。
1.
2------>
3.
2人目の生徒は靴ひもをほどきました。今、彼女は立ち止まり、再び縛られています。このため、2回目の終了時間が延長され、3回目の開始時間が遅れました。
1.
--2.--->
3.
このパターンは、3番目が2番目からバトンを取得してレースを終了するまで続きます。
非同期
同じ道を歩いている10人のランダムな人を想像してみてください。もちろん、彼らは順番待ちではなく、道路上のさまざまな場所をさまざまなペースでランダムに歩いています。
2人目の靴ひもがほどかれた。彼女はそれを再び縛りつけるために立ち止まった。
しかし、誰も彼女が縛られるのを待っていません。他のすべての人は、以前と同じように、同じペースで歩き続けています。
10--> 9-->
8--> 7--> 6-->
5--> 4-->
1--> 2. 3-->
a> b> c> d>のようなシーケンスを実行するとき、実行の途中で次のようなエラーが発生した場合:
a
b
c
fail
次に、最初からやり直します。
a
b
c
d
これは同期です
ただし、実行する同じシーケンスa> b> c> d>があり、途中でエラーが発生した場合:
a
b
c
fail
...しかし、最初からやり直すのではなく、失敗した時点からやり直します。
c
d
...これは非同期として知られています。
同期対並列とシリーズを混同しています。同期とは、同時にすべてを意味します。同期したとは、互いに関連していて、連続して、または一定の間隔で意味することができます。プログラムはすべてを実行している間、連続して実行されます。辞書を入手してください...これが私たちが甘いお茶を持っている理由です。あなたはお茶または甘味のあるお茶を持っています。
同期とは、基本的に一度に1つの処理しか実行できないことを意味します。非同期とは、一度に複数の処理を実行でき、次の処理に進むために現在の処理の実行を終了する必要がないことを意味します。
朝食の作成方法の例を使用してください
料理の経験がある場合は、これらの命令を非同期で実行します。あなたは卵の鍋を温め始め、次にベーコンを始めます。パンをトースターに入れて、卵を作ります。プロセスの各ステップで、タスクを開始してから、準備ができているタスクに注意を向けます。
朝食を調理することは、並列ではない非同期作業の良い例です。1人のユーザー(またはスレッド)がこれらのすべてのタスクを処理できます。朝食の類推を続けると、最初の人が完了する前に次のタスクを開始することで、一人が非同期に朝食を作ることができます。誰かがそれを見ているかどうかにかかわらず、調理は進行します。卵の鍋を温め始めたら、すぐにベーコンを炒めることができます。ベーコンが始まったら、パンをトースターに入れます。
並列アルゴリズムの場合、複数のクック(またはスレッド)が必要になります。卵を作ったり、ベーコンを作ったり。それぞれがその1つのタスクだけに集中します。各クック(またはスレッド)は同期的にブロックされ、ベーコンが反転する準備ができるか、トーストがポップするのを待ちます。
非同期プログラミングの概念からの参照
「に関しては、同時に(時々混乱さ)同期実行の」定義、ここではそれを理解するための良い方法です:
同期実行:コードブロック内のすべてのタスクは、すべて同時に実行されます。
非同期実行:コードのブロック内のすべてのタスクがすべて同時に実行されるわけではありません。