0

現在、無限ループの新しいスレッドでアプリケーションのメモリの外部を読み取っています

public void ReadMemory()
{
//read memory
Thread.Sleep(10);
}

残念ながら、1ミリ秒の睡眠でも、1分間に60〜100回のループが発生する可能性があります。スリープがない場合、1000〜1500 /秒のループになりますが、多くのCPUが必要になります。それで私にできることは何もないとは信じられないので、ここであなたに尋ねます:P。別のスレッド(またはその他のスレッド)にバックグラウンド動作関数をいくつか追加したいので、CPU使用率が問題になる可能性があります

10ミリ秒の休止でそのようなループの量を減らさないものはありますか?

4

3 に答える 3

4

CPU使用率について心配する必要はありません。それは無意味な概念です。

「少し実行するコード」や「コードをゆっくり実行してCPUを25%しか消費しない」などのことはありません。

最も低いレベルでは、それはバイナリのことです。コードが実行され、実行されているコアの100%を消費するか、そうでない場合、0%のCPUを使用します。

OSが表示するCPU使用率は、移動平均です。

したがって、質問する必要があるのは、「CPUをあまり使用せずにコードを実行するにはどうすればよいか」ではなく、「実行すべきでないときにコードを実行するか」ということです。コードを実行したい場合は、少なくとも一時的に100%CPUを使用しますが、問題はありません。

Sleep()アプリケーションで呼び出しがどのような役割を果たしているのかは明確ではありません。何を待っていますか?各反復の間に数ミリ秒を通過させたいだけですか?それとも、特定のイベントが発生するのを待っていますか?

いずれにせよ、を呼び出すときはSleep(10)、スレッドを10ミリ秒中断していません。少なくとも10ミリ秒中断しています。OSにスレッドをスリープキューに入れるように指示しているので、10ミリ秒が経過すると、スレッドは再度実行できると見なされます。ただし、それでもOSがスレッドのスケジューリングに取り掛かることに依存します。これにはさらに10ミリ秒かかる場合があります(さまざまな要因に応じて、それ以上またはそれ以下)。

Windowsでは、Sleep(0)これは特殊なケースであり、実験することができます。実際にスレッドを一時停止する代わりに、スレッドが現在のタイムスライスで完了したことをOSに通知し、他のスレッド/プロセスを実行できるようにしますが、スレッドをスリープ状態にすることはありません。次回のコンテキストスイッチ時にスケジュールする資格があります。発生します。したがって、他のスレッド/プロセスが実行される機会を確実に得ることが目標である場合は、呼び出しSleep(0)がそれを実行する方法である可能性があります。

もう1つの方法は、問題を無視し、OSがプロセスのスケジュール方法を知っていることを信頼することです(これはかなり安全な仮定です。他のバックグラウンドプロセスが不足していることを実際に確認しない限り、これについて心配する必要はありません。おそらくそうではないでしょう)。

そして最後に、もちろん、スレッドとプロセスの優先順位を設定して、どのスレッドをスケジュールするかをOSに示唆することができます。このスレッドに低い優先度を与えると、優先度の高いスレッドが使用できない場合にのみスケジュールされ、他のスレッドが不足しないようにします。

于 2012-07-14T14:40:16.157 に答える
1

スレッドは、他のスレッドがそのCPU時間を必要としない限り、できるだけ多くのCPU時間を消費するように設計されています。 CPUが他のタスクを実行できるようにスレッドを解放しようとしているだけの場合は、実行しないでください。Windowsは、必要に応じて、他のスレッドに自動的に馬力を割り当てます。

于 2012-07-14T14:27:53.023 に答える
1

繰り返しごとに寝るのではなく、たまにしか寝ない場合はどうでしょうか。

何かのようなもの :

public class Reader
{
    private static int count= 0;

    public void ReadMemory()
    {
        //read memory

        // Sleep every 501 iterations
        if (Reader.count++ == 500)
        {
            Thread.Sleep(1);
            Reader.count  = 0;
        }
    }
}

1秒間に約1000回の反復で実行していて、切り替えの実行に1秒かかる場合、これは、0.5秒間フルパワーで実行し、次に1秒間スロットルバックしてから、フルパワーに戻ることを意味します。平均すると、1秒あたり333回の反復になります。

もちろん、500以外の値で実験してみることができます。

于 2012-07-14T15:38:05.177 に答える