さまざまなソースを検索しましたが、NSThreads
とGCDの違いがよくわかりません。私はOS Xプラットフォームがまったく新しいので、これを完全に誤解している可能性があります。
私がオンラインで読んだことから、GCDは基本的なスレッド(POSIX、NSThreads
など)とまったく同じことをしている一方で、より専門的な専門用語(「ブロック」)を追加しているようです。基本的なスレッド作成システム(スレッドの作成、関数の実行)が複雑すぎるだけのようです。
GCDとは正確には何で、なぜ従来のスレッド化よりもGCDが好まれるのでしょうか。 GCDではなく従来のスレッドを使用する必要があるのはいつですか?そして最後に、GCDの奇妙な構文の理由はありますか? (単に関数を呼び出す代わりに「ブロック」)。
私はMac OS X 10.6.8 Snow Leopardを使用していますが、iOS用のプログラミングをしていません-Mac用のプログラミングをしています。 CocoaでXcode 3.6.8を使用して、GUIアプリケーションを作成しています。
発送のメリット
ディスパッチの利点は主にここに概説されています:
この考え方は、パラダイムがMOSTコードに簡単に適合するため、ユーザー側の作業を排除するというものです。
- アプリケーションのメモリ空間にスレッドスタックを格納するためにアプリケーションが支払うメモリペナルティが軽減されます。
- スレッドの作成と構成に必要なコードが不要になります。
- スレッドでの作業の管理とスケジュールに必要なコードを排除します。
- それはあなたが書かなければならないコードを簡素化します。
経験的に、@synchronized
の代わりにGCDタイプのロックを使用すると、マイクロベンチマークが誤っている可能性がありますが、約80%以上高速になります。続きを読む ここ 、ただし、書き込みと非同期にするというアドバイスは多くの場合当てはまりませんし、遅いです(ただし非同期です)。
スレッドの利点
なぜスレッドを使い続けるのですか?同じドキュメントから:
キューはスレッドを置き換えるための万能薬ではないことを覚えておくことは重要です。キューが提供する非同期プログラミングモデルは、遅延が問題にならない状況に適しています。キューはキュー内のタスクの実行優先度を構成する方法を提供しますが、より高い実行優先度は特定の時間でのタスクの実行を保証するものではありません。したがって、オーディオやビデオの再生など、待ち時間を最小限に抑える必要がある場合は、スレッドがより適切な選択です。
キューを使用する理想的なソリューションを私が個人的に見つけていない別の場所は、絶えず再スケジュールする必要があるデーモンプロセスです。それらを再スケジュールすることはできませんが、NSThreadメソッド内でのループはより簡単です(私は思います)。 編集:これで、このコンテキストでもGCDスタイルのロックが高速になり、GCD内でループを実行できると確信しました-派遣オペレーション。
Objective-Cのブロック?
Objective-Cでは、構文がひどいため、ブロックは本当に恐ろしいものです(少なくとも、Xcodeはオートコンプリートに役立つことがあります)。 Ruby(または他の言語であれば、かなりの数))でブロックを見ると、それらがディスパッチ操作にどれほどシンプルでエレガントであるかがわかります。 Objective-C構文ですが、例からコピーすることに慣れると思います:)
あなたは ここからの私の例 が役立つか、気を散らすかもしれません。わからない。
これまでの答えは、単一のアプリケーションのドメイン内のスレッドとGCDのコンテキストと、プログラミングでの違いについてですが、常にGCDを好む理由は、マルチタスク環境が原因です(iOSではなくMacOSXを使用しているため)。 。マシン上でアプリケーションが実行されている場合aloneスレッドは問題ありません。たとえば、ビデオ編集プログラムがあり、ビデオに何らかのエフェクトを適用したいとします。レンダリングは、8コアのマシンで10分かかります。いいよ.
ここで、ビデオアプリがバックグラウンドで動作している間に、画像編集プログラムを開いて高解像度の画像を再生し、特別な画像フィルターを適用することを決定します。賢い画像アプリケーションは、8つのコアがあることを検出し、処理する8つのスレッドを開始します。画像。いいですね。それ以外はパフォーマンスがひどいです。画像編集アプリは動画アプリについて何も認識していません(その逆も同様)。したがって、どちらもそれぞれ最適な数のスレッドを要求します。そして、コアが1つのスレッドから別のスレッドに切り替えようとしている間、痛みと血が流れます。飢餓を回避するために、CPUは最終的にすべてのスレッドを実行させます。ただし、この状況では、ビデオに対して4つのスレッドのみを実行する方が最適です。アプリと画像アプリ用の4つのスレッド。
詳細なリファレンスについては、HTTPサーバーのベンチマークを確認できる http://deusty.blogspot.com/2010/11/introducing-gcd-based-cocoahttpserver.html を参照してください。 GCD対スレッドを使用して、それがどのようにスケーリングするかを確認します。マルチアプリ環境のマルチコアマシンでスレッドに問題があることを理解したら、スレッドが常に最適であるとは限らないという理由だけで、常にGCDを使用する必要があります。ただし、OSは負荷に応じてアプリごとのスレッド使用量をスケーリングできるため、GCDは潜在的に可能です。
私たちのマシンにはこれ以上GHzが搭載されないことを覚えておいてください。今後はコアの数が増えるだけなので、この環境に最適なツールを使用することがあなたの義務です。それがGCDです。
ブロックにより、実行するコードのブロックを渡すことができます。 「奇妙な構文」を通過すると、それらは非常に強力になります。
GCDはキューも使用します。キューを適切に使用すると、個別のキューで実行されているコードが分離されている場合、ロックフリーの同時実行性に役立ちます。これは、デッドロックの可能性を最小限に抑えながら、バックグラウンドと同時実行性を提供するためのより簡単な方法です(正しく使用した場合)。
「奇妙な構文」は、C++で演算子としてオーバーロードされなかった数少ない記号の1つであるため、キャレット(^)を選択したためです。
アプリケーションに同時実行性を追加することになると、ディスパッチキューには、スレッドに比べていくつかの利点があります。最も直接的な利点は、ワークキュープログラミングモデルのシンプルさです。スレッドでは、実行する作業と、スレッド自体の作成と管理の両方のコードを記述する必要があります。ディスパッチキューを使用すると、スレッドの作成や管理を気にすることなく、実際に実行したい作業に集中できます。代わりに、システムがスレッドの作成と管理をすべて処理します。利点は、システムが単一のアプリケーションよりもはるかに効率的にスレッドを管理できることです。システムは、使用可能なリソースと現在のシステム状態に基づいてスレッド数を動的にスケーリングできます。さらに、システムは通常、自分でスレッドを作成した場合よりも速くタスクの実行を開始できます。
ディスパッチキューのコードを書き換えることは難しいと思うかもしれませんが、ディスパッチキューのコードを記述する方が、スレッドのコードを記述するよりも簡単なことがよくあります。コードを作成する鍵は、自己完結型で非同期に実行できるタスクを設計することです。 (これは実際には、スレッドとディスパッチキューの両方に当てはまります。)
...
シリアルキューで実行されている2つのタスクが同時に実行されないことを指摘するのは正しいことですが、2つのスレッドが同時にロックを取得すると、スレッドによって提供される同時実行性が失われるか大幅に減少することを覚えておく必要があります。さらに重要なことに、スレッドモデルでは2つのスレッドを作成する必要があり、カーネルとユーザー空間の両方のメモリを消費します。ディスパッチキューは、スレッドに対して同じメモリペナルティを課さず、使用するスレッドはビジー状態に保たれ、ブロックされません。
GCD(Grand Central Dispatch):GCDは、アプリケーションがブロックオブジェクトの形式でタスクを送信できるFIFOキューを提供および管理します。ディスパッチキューに送信された作業は、完全に管理されているスレッドのプールで実行されますシステムによって実行されます。タスクが実行されるスレッドについては保証されません。スレッドでGCDを使用する理由:
CPUコアが実行している作業量CPUコアの数。生成するスレッドの数。 GCDが必要な場合は、カーネルにアクセスしてリソースについて通信できるため、スケジューリングを改善できます。カーネルへの負荷を減らし、OSとの同期を改善GCDは、作成して破棄する代わりに、スレッドプールから既存のスレッドを使用します。システムのハードウェアリソースを最大限に活用しながら、オペレーティングシステムが現在実行中のすべてのプログラムの負荷と、暖房やバッテリーの寿命などの考慮事項をバランスさせることができます。
スレッド、オペレーティングシステム、およびGCDとの経験を共有しましたAT http://iosdose.com