1

Macアプリケーション( NSRunLoop )に適用される実行ループをよりよく理解しようとしていますが、これはより一般的な質問になる可能性もあります。NSRunLoopのドキュメントには次のように書かれています。

...コードは、実行ループを駆動するwhileorループを提供します。forループ内で、run loopオブジェクトを使用して、イベントを受信し、インストールされたハンドラーを呼び出すイベント処理コードを「実行」します。

ドキュメントには、次のようなコード例があります。

BOOL shouldKeepRunning = YES;
NSRunLoop *theRL = [NSRunLoop currentRunLoop];
while (shouldKeepRunning && [theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);

したがって、コードは、終了する必要があると判断されるまで、実行ループを呼び出し続けます。メソッド「-runMode:beforeDate:ループを1回実行し、指定された日付まで指定されたモードでの入力をブロックします。」また、-run「レシーバーを永続的なループに入れ、その間に接続されているすべての入力ソースからのデータを処理する」方法もあります。

実行ループを繰り返し呼び出す(または-run、これ自体がそう思われる)呼び出しがCPUを消費しないようにするにはどうすればよいですか?Cocoaアプリケーションは、メインの実行ループが実行されている間、バックグラウンドでアイドル状態になり、CPU時間をゼロ(またはほぼゼロ)消費します。

そして、内-runMode:beforeDate:で、CPUをポーリングして消費することなく、入力が受信されるかタイマーが起動するまで、実行ループをどのようにブロックできますか?

4

1 に答える 1

2

これは、Mac OS X の内部を突っ込む良い口実でした! 幸いなことに、Core Foundation の関連部分はオープン ソースです。

「プログラムがCPU を使用せずにXを待機するにはどうすればよいでしょうか?」に対する通常の回答です。「カーネルがやった」です。この場合、実行ループを実行することは、カーネルに何を待っているかを伝えてから、カーネルのコンテキスト スイッチを解放することを意味します。この場合、実行ループはmach_msgフラグでほとんどの時間を費やしますMACH_RCV_MSGが、これは実際にはカーネルへの単なるシステム コールであり、実行する他のスレッドをスケジュールすることになります。最終的に、興味深いことが起こります。つまり、Mach メッセージが Mach ポートに送信され、カーネルがブロックされたスレッドを起動してメッセージを配信します。mach_msgプログラムは、これを関数が戻ると見なします。

Mach メッセージをあなたに送信するには、あらゆる種類の内部的な方法があります。たとえば、 を設定するNSTimerと、おそらくmk_timer_armシステム コールに至るまで機能し、一定時間後に Mach メッセージがどこかに送信されます。したがって、実行ループは派手な無限ループではなく、ディスパッチャーであり、カーネルと Cocoa (または Core Foundation) フレームワーク間のマッピングです。

メッセージを待っているためにカーネルがスレッドを一時停止した場合、実際には CPU 時間を使用していないことは言うまでもありません。これが、アプリケーションがアイドル状態に見える理由です。最新のカーネルを使用しているのに、なぜ無限ループに悩まされるのでしょうか?

于 2012-08-21T04:19:14.817 に答える