2009-08-03 5 views
18
#include <stdio.h> 

int main() { 
    while(!DONE) { 
    /* check for stuff */ 
    } 
    return 0; 
} 

上記のコードサンプルでは、​​DONEがtrueになるまで100%CPUを使用しています。どのようにループし、完了時に終了するが、100%CPUを使用しないプログラムを実装できますか? 現代の言語では、App.ProcessMessagesなどのものを使用して、OSにその時点の制御を与えてからループに戻ることができます。C 100%cpuなしのメインループ

I(ポータブルソリューションは、素晴らしいことだ!)最新のGCC、LinuxとWindowsを使用して、明らかにC、...で新たなんだ

+8

を推測十分だろうです。 –

+2

'DONE'とは何で、何がゼロ以外になるのでしょうか?恐らく、 'stuff for check'がDONEを非ゼロに設定する何かを評価するまで、処理を続けるのは理にかなっていますか? –

+0

Lasse V. Karlsen: あなたのソリューションは理にかなっているようです(おそらくそれほど意味がありますが、その知識はありません)。あなたは詳細を教えていただけますか?スレッドを調べるべきですか? Charles Bailey: DONEは、(DONEの代わりに)intにする必要があり、ユーザーがアプリを終了するときに1に設定されます。 十分に説明できないのであれば申し訳ありません。 – pwseo

答えて

16

このループの中で何をしたいかによって異なります。

ループ内で待機している場合(つまり、何かをしている場合)、システムはシステムリソースを無駄にしてしまい、代わりに何も返さないことになります。例えば、ファイル操作(stdinはファイルでもあります)は、移植可能なメカニズムになります。これは、データが利用可能になるまで他のアプリケーションへの道を譲ります。より具体的には、OSに依存することが多いセマフォーやシグナルにダイブする必要があるかもしれません。

有用なこと(つまり、大量のデータを処理する)なら、100%プロセッサーが私たちであることを意味します最も効率的な方法で編集しました。オペレーティングシステムに依存して、優先度の高い他のタスクや優先度の高いタスクに頼ることができます。

スリープのような機能を使用すると、CPU使用率は低下しますが、アプリケーションの処理速度は低下します。許容可能な性能とCPU負荷との間にトレードオフが必要です。最大実行速度はスリープパラメータで定義され、CPU速度ではなくなります。また、電力が問題(バッテリ寿命)である場合は、CPUをスリープ解除(休止期間の終了)する必要があります。システム資源の異なる浪費である。

+0

私はセマフォとシグナルを学ばなければならないと思います。 それに関する具体的な指針はありますか? :) – pwseo

+2

メインループ内にはどのような処理がありますか? メッセージ、シグナル、セマフォーは、基本言語とオペレーティングシステムによって大きく関連しています。たとえば、http://www.ibm.com/developerworks/eserver/library/es-win32linux-sem.htmlは、WindowsとLinuxのセマフォーの処理方法を示しています。両方をサポートする必要がある場合は、POSIX(Windowsの場合はオプション、cygwinの場合)を使用するか、OSごとに作成するプラットフォーム依存モジュールにコードを入れてください。 – Adriaan

1

使用

スリープ(int型ミリ秒)

+3

sleepへの引数は、実際には数ミリ秒ではなく数ミリ秒です。 –

+1

私は実際にはOSに依存していると思う...あなたがUnix/Linux/* BSDの下で秒単位のパラメータについて正しいのだが、Windowsの下ではミリ秒ということを思い出すと思う。間違っている... – Nicolas

+5

sleep()には秒がかかります。 usleep()(BSDとPOSIX)はマイクロ秒かかる。 nanosleep()(POSIXも)はナノ秒かかる。 – qrdl

3

何あなたは確かにあなたをチェックしていますか?

ハードウェアや他のプロセスによって変更された揮発性のものをチェックしている場合は、ループ内でsleepに電話するだけです。

ファイルディスクリプタやネットワークソケット記述子で待っている場合は、消費の準備ができたデータを持っている記述子を待つために、あなたのループ内でselectまたはpollを使用したいと思うでしょう。

0

yield()。

+0

これはC標準でもPOSIXでも定義されていないため移植性がありません。 –

+1

他のプロセスに時間を割いても、他のプロセスが消費していない時間を奪うのではないでしょうか? – liori

0

私が正しく推測している(私はそれについて知らない)場合、App.ProcessMessagesに相当するIOをブロックしている。また、ポーリングを使用するマルチタスクOSでのCの実装についてはわかりませんが、標準のC IOは安全です。

5

あなたの2つのオプションは、ポーリングと何らかのイベント通知です。

ポーリングはプログラムするのが最も簡単です。基本的には、ループを通過するたびに短い時間スリープします。これにより、プロセッサが他のタスクに解放されます。欠点は、あなたの "物事をチェックする"コードに遅れがあることです - あなたが1秒間眠っている場合、コードが条件を検出するまでには1秒ほどかかることがあります。ここのコードは簡単に移植できます。

もう1つのオプションは、POSIXの条件付きイベントまたはWindowsイベントなどを待つことです。このコードは変更されるだけでなく、「確認しているもの」が完了したことを示すフラグをトリガする必要があります。プラットフォームを抽象化するためのライブラリはおそらくありますが、これはやや移植性の低いコードになります。しかし、イベントに即座に結果が得られ、プロセッサの時間を無駄にすることなく、そこにないものをチェックすることができます。

+1

+1 POSIX同期の使用を提案します。 –

9

あなたはいくつかの選択肢があります。

  1. 利用スリープ()定期的に中断するためのプロセスを強制し、他のプロセスが優先順位の低いレベルでCPU
  2. 実行使用できるようにする - へのOSの原因となりますあなたがより速くあなたがそれを処理できるよりも、仕事を取得した場合、それは実際に作業
  3. を行っていない限り、すべてのCPU時間を消費してからプロセスを続けるであろう - 仕事が利用可能である場合を検出するためにミューテックスまたは他の同期オブジェクトを使用し
  4. 少ないCPU時間を割り当てます - あなたはまだ必要があるかもしれません。 CPUを完全に消費するのを避けるために、ある種のスリープ/優先順位モデルがあります。

オプション#2は、プラットフォーム/ OSニュートラルなやり方でやりにくい場合があります。最善の方法は、プロセスを起動し、ランタイム環境で優先度を変更することです。

0

windowsでは、windows.hで定義されたSleep(intミリ秒)を使用できます。

2

私が正しく理解していれば、DONEを他のスレッドから変更することができます。そうであれば、条件変数は意味をなさない。 pスレッドと、一つだろう。

待機スレッドで:変更されたが完了したら、他のスレッドで

pthread_mutex_lock(&mutex); 
while (!DONE) { 
    pthread_cond_wait(&cond, &mutex); 
} 
pthread_mutex_unlock(&mutex); 

pthread_mutex_lock(&mutex); 
DONE = 1; 
pthread_cond_signal(&cond); 
pthread_mutex_unlock(&mutex); 
+0

他のスレッドからスレッドをアンロックできますか? – user457015

1

Sleep(0);は、私はあなたが同期オブジェクト、それは、あなたがすべてでCPUを消費しないだろう、そのように知らされるまであなたが待つことができるものを使用する必要があり