0

関連するが同じではないことに注意してください: iPhone - Grand Central Dispatch メインスレッド

私は何度もこの質問に失敗したので、ここにソースコードがあります:

メインスレッドで

dispatch_async( dispatch_get_main_queue(), ^{ NSString * str = @"Interrupt myself to do something."} );

スレッドが切り替わると、レジスタがスレッド ローカル ストレージに格納され、コンテキストが切り替わり、プログラム カウンターの新しい場所から実行されます (これは、単に別のスタックを使用するプログラムのコピー内にあり、登録)、メインスレッドに「戻ります」。

それが自分自身を中断するとき、私はそれがいつすべきかを決定するものと、スレッドローカルのものに何が起こるのか疑問に思っています。

私はこれについて少し読みましたが、プログラムが連続的ではないという事実にまだ頭を悩ませています。それらは、「OS がプロセスのチャンクまたはそのチャンク (スレッド) を実行することを決定したときに、小さなチャンクで実行するものです。

私は独学なので、学者にとって標準的なレジスター/asm の知識が不足している可能性があります。

ありがとう。コードが役立つはずです。これは iOS 固有ですが、回答/質問はメインからメインへの言語に関連していると思います。

過去のすべての試みは、私がこれを求めている理由を無視する長い回答をもたらしたので、最後にもう一度繰り返します....

これは同じスレッド用です。メインからメインへ。それは本当にそれ自体を停止し、プログラムカウンターを別の場所に移動し、移動してからブロックで終了しますか? また、これらのことは通常ブランチで変更しないでください (if/for およびブロックも)。

私を正しい方向に向けることもできますが、私が言ったように、以前は質問が誤解されていました.

4

2 に答える 2

1

GCD の内部にアクセスせずに具体的に質問に答えるのは難しいですが、一般的に答えはノーです。作業単位をディスパッチ キューに追加するだけでは、実行中のコードがすぐに中断されることはありません。

あなたが示唆しているように、コンテキストスイッチは状態の保存と復元の観点からだけでなく、プロセッサが命令パイプラインをダンプする必要があり、サイクルが無駄になります。

通常、オペレーティング システムは現在のタスクを一時停止するまで (たとえば、ネットワークやその他の IO 操作を待機する)、または何らかの外部イベント (電話のホーム キーを押す) によって中断されるまで、現在のタスクを実行し続けますが、防止するための時間制限もあります。デバイス全体のロックによるランナウェイ タスク (これは、タスクが CPU を解放する必要がある協調マルチタスクとは対照的に、プリエンプティブ マルチタスクです)

dispatch_async では、現在のコード ブロックに関連してコードがいつ実行されるかは保証されません。コード ブロックは、キューの次のブロックでさえない可能性があります。他のスレッドが、このブロックの前に他の作業単位をキューに追加している可能性があります。

于 2014-08-22T00:06:04.597 に答える
0

あなたを混乱させているのはdispatch_async( dispatch_get_main_queue())、メインスレッドのキューで実行するコードを送信する の使用だと思います。


メイン キューで dispatch_async を使用する:

を呼び出すとdispatch_async( dispatch_get_main_queue())、作業単位がメイン キューに追加され、メイン スレッドからジョブが実行されます。

この呼び出しをメイン スレッドから実行しても、結果は同じです。作業は、後で処理するためにメイン キューに追加されます。

メイン スレッドからこの呼び出しを行うと、コードが戻るまで、システムはメイン キューで実行する作業をチェックしません。

これをワンクックキッチンと考えてください。料理人は仕事中、皿洗い場に皿を並べます。彼は、現在行っていることの限界点に到達するまで、料理をすることをやめません。その時点で、彼は皿のトレイを取り、食器洗い機に入れ、調理に戻ります。

料理人は、限界点に達するたびに皿をチェックしなければならないことを知っており、料理に戻る前に皿洗いのタスクを完了します。


バックグラウンド キューでの dispatch_async の使用:

バックグラウンド キューへの dispatch_async 呼び出しは、2 人用のキッチンのようなものです。同時に稼働する食器洗い機があります。料理人は食器のトレイを食器洗いステーション (キュー) に置き、食器洗い機 (別のスレッド) は前のタスクが終了するとすぐにそのタスクを取得しますが、料理人は料理に取り組み続けます。

上記は、最近の標準である複数のプロセッサを搭載したマシンを想定しています。各プロセッサは、複数のタスクをやりくりすることなく、同時に作業を行うことができます。

プリエンプティブ マルチタスキングを備えたシングルコア システムで実行している場合、個別のスレッド/バックグラウンド キューにタスクを送信すると、複数のプロセッサがある場合と同じ効果がありますが、OS はジャグリング動作を実行する必要があります。キッチンには 1 人しかいませんが、彼は複数の帽子をかぶっています。その人が料理の仕事をしていると、OS が「Switch!」と叫びます。料理人は自分がしていたことをメモし (状態を保存)、ディッシュピットに飛び込んで皿洗いを開始し、OS が「スイッチ!」と叫ぶまで皿洗いを続けます。ワーカーは再び状態を保存し、次のロールに切り替えて、中断されたそのロール (料理人) を取り上げます。

ワーカーがロールを切り替えるたびに現在の状態を保存し、保存された状態を別のロールにロードして続行する必要があるため、マルチタスクはシングルコア システムではよりコストがかかります。これらのコンテキストの切り替えには時間がかかります。

于 2016-12-15T19:24:05.220 に答える