web-dev-qa-db-ja.com

スレッドと非同期

私は、この本当に良い記事から、スレッドモデルのプログラミングと非同期モデルを比較してきました。 http://krondo.com/blog/?p=1209

ただし、この記事では次の点に言及しています。

  1. 非同期プログラムは、I/Oが発生するたびにタスクを切り替えることにより、同期プログラムよりも優れています。
  2. スレッドはオペレーティングシステムによって管理されます。

スレッドは、Ready-QueueとWaiting-Queue(他のキュー)の間でTCBを移動することにより、オペレーティングシステムによって管理されていることを読んだことを覚えています。この場合、スレッドは待機に時間を無駄にしませんか?

上記に照らして、スレッド化されたプログラムに対する非同期プログラムの利点は何ですか?

62
user277465
  1. スレッドセーフなコードを記述することは非常に困難です。非同期コードを使用すると、コードが1つのタスクから次のタスクに移行する場所を正確に把握できるため、競合状態を解決するのがはるかに難しくなります。
  2. 各スレッドは独自のスタックを持つ必要があるため、スレッドはかなりの量のデータを消費します。非同期コードを使用すると、すべてのコードが同じスタックを共有し、タスク間でスタックを連続的に巻き戻すためにスタックが小さくなります。
  3. スレッドはOS構造であるため、プラットフォームがサポートするメモリが増えます。非同期タスクにはこのような問題はありません。
65
doron

スレッドを作成するには2つの方法があります。

同期スレッド-親は1つ(または複数)の子スレッドを作成し、各子が終了するまで待機する必要があります。同期スレッドは、多くの場合 fork-joinモデル と呼ばれます。

非同期スレッド-親と子は、同時に/独立して実行されます。通常、マルチスレッドサーバーはこのモデルに従います。

リソース- http://www.Amazon.com/Operating-System-Concepts-Abraham-Silberschatz/dp/047012872

10
Aidan Melen

まず、スレッドの実装およびスケジュール方法の詳細の多くは非常にOS固有であることに注意してください。一般に、OSとハードウェアは、シングルプロセッサシステムで非同期に、またはマルチプロセッサで並列に、スレッドが効率的に実行されるように調整しようとするため、スレッドが互いに待機することを心配する必要はありません。

スレッドが何か(I/Oなど)の待機を完了すると、スレッドは実行可能と見なすことができます。実行可能なスレッドは、すぐに実行されるようにスケジュールされます。これが単純なキューとして実装されるか、より洗練されたものとして実装されるかは、やはりOSとハードウェアに固有です。ブロックされたスレッドのセットは、厳密に順序付けられたキューではなくセットと考えることができます。

シングルプロセッサシステムでは、ここで定義されている非同期プログラムはスレッドプログラムと同等であることに注意してください。

4
Joe Kearney
  1. IOを含まない2つのタスクがあると仮定します(マルチプロセッサマシン上)。この場合、スレッドは非同期よりも優れています。 Asyncはシングルスレッドプログラムのようにタスクを順番に実行するためです。ただし、スレッドは両方のタスクを同時に実行できます。

  2. IO(マルチプロセッサマシン上)を含む2つのタスクがあるとします。この場合、非同期とスレッドの両方がほぼ同じパフォーマンスを発揮します(パフォーマンスは、コアの数、スケジューリング、タスクの集中処理量などによって異なる場合があります)。また、非同期は、マルチスレッドプログラムを介してプログラムするのに必要なリソース量が少なく、オーバーヘッドが少なく、複雑さが軽減されます。

使い方?スレッド1はタスク1を実行します。これはIOを待機しているため、IO待機キューに移動されます。同様に、スレッド2はIOを含むため、タスク2を実行し、IO待機キューに移動します。 IO要求が解決されるとすぐに準備完了キューに移動されるため、スケジューラはスレッドの実行をスケジュールできます。

非同期はタスク1を実行し、IOの完了を待たずにタスク2を続行し、両方のタスクのIOが完了するのを待ちます。 IO完了の順にタスクを完了します。

Webサービス呼び出し、データベースクエリ呼び出しなどを含むタスク、プロセス集中型タスクのスレッドに最適な非同期。

以下のビデオでは、aboutAsync vs Threaded modelの説明と、使用するタイミングなどについて説明します。 https://www.youtube.com/watch?v=kdzL3r-yJZY

これが役に立てば幸いです。

3
Lakshmipathi

http://en.wikipedia.org/wiki/Thread_(computing)#I.2FO_and_scheduling を参照してください

ただし、(カーネルスレッドではなく)ユーザースレッドまたはファイバーでブロックシステムコールを使用すると、問題が発生する可能性があります。ユーザースレッドまたはファイバーがブロックするシステムコールを実行する場合、プロセス内の他のユーザースレッドおよびファイバーは、システムコールが戻るまで実行できません。この問題の典型的な例は、I/Oを実行する場合です。ほとんどのプログラムは、I/Oを同期的に実行するように記述されています。 I/O操作が開始されると、システムコールが行われ、I/O操作が完了するまで戻りません。その間、プロセス全体がカーネルによって「ブロック」され、実行できなくなります。これにより、同じプロセス内の他のユーザースレッドとファイバーが実行されなくなります。

これによると、プロセス全体がブロックされる可能性があり、IOで1つのスレッドがブロックされると、スレッドはスケジュールされません。これはOS固有のものであり、常に保持されるとは限りません。

0
gleery

非同期I/Oは、ドライバーにジョブを実行するスレッドが既に存在するため、機能を複製し、オーバーヘッドが発生することを意味します。一方、多くの場合、ドライバースレッドの正確な動作は文書化されておらず、複雑なシナリオでは、タイムアウト/キャンセル/開始/停止の動作、他のスレッドとの同期を制御する場合、独自のスレッドを実装するのが理にかなっています。また、同期用語で推論する方が簡単な場合もあります。

0
Boris Geller