2

何かのステータスをポーリングするタイトなループがある場合、CPUを使用したい他のプロセスの邪魔にならずにポーリングを実行する方法がよくわかりません。たとえば、これを行う:

while (state == BUSY) state = check_state();

リソースの無駄のようです。これを行うための最良の方法は次のとおりだと思います。

while (state == BUSY) {
    sched_yield();
    state = check_state();
}

これを実行している間にCPUを100%消費したとしても、topはプロセスをスリープ状態としてリストすることを期待しています。このように、プロセスは(私は願っています)「うまく」ポーリングします。しかし、それは起こりません。現時点で私は

while (state == BUSY) {
    sleep(1);
    state = check_state();
}

これは完全に受け入れられますが、これよりもうまくいくと思います。これを行うための標準的な方法はありますか?

4

5 に答える 5

3

sched_yield()をスピンしないでください。スケジューラーの優先順位の検出が非常に悪くなり、パフォーマンスの観点から相互運用性が高い場合でも、バッテリーの寿命や消費電力のメトリックが破壊されます。アプリケーションが遅延に耐えられる場合は、タイムアウトを使用したポーリング(10Hzなどの短いポーリングでも)が非常に望ましいですが、それでも理想的ではありません。

正しい答えは、check_state()が実際に何をする必要があるかによって異なります。状態の変化がカーネルに表示されるイベントであり、ブロックできるように調整できないことを絶対に確信していますか?

于 2009-10-07T18:49:01.670 に答える
1

残念ながら、良心的なポーリングのようなものはありません。ポーリングは、常に反応時間とリソース消費の間のトレードオフです。ポーリング期間が短いほど、反応時間は長くなりますが、リソース消費は高くなります。ポーリング期間が長いほど、節約できるエネルギーは多くなりますが、アプリケーションの反応性は低下します。

ポーリングは、どのように見ても、常に醜いものです。あなたが正しい方法で物事を行おうとしているなら、あなたはより良いメカニズム、すなわち通知を使わなければならないでしょう。つまり、check_state()APIは、状態をポーリングすることしかできないため、悪いAPIです。状態が変化したときに通知するように設計された関数が必要です。通常、このような関数は、状態が変化したときに一部のfdを読み取り可能にするため、同期または非同期でfdのイベントを待機し、そのようなイベントが発生したときにのみウェイクアップできます。

于 2011-06-23T11:21:59.480 に答える
1

これはあなたが世論調査や世論調査を使うことができるものだとは思いませんか

于 2009-10-07T18:59:36.763 に答える
0

libeventまたはlibevを使用できると思います。

どちらもこのようなものを処理するための機能を提供します。

于 2009-10-07T19:04:04.620 に答える
0

私のリアルタイム作業では、通常、妥当なタイムアウト(10usなど)を選択し、条件とRDTSC(タイムスタンプカウンター)をスピンします。

非常に長い時間(10msより長い時間など)スピンしたい場合は、そこに小さなスリープステートメントを入れて、他のものが実行される機会を得ることをお勧めします。

于 2009-10-07T19:25:56.167 に答える