2012-03-01 22 views
8

OSを予想以上に長く眠ります。私はそれを100回ループして、スリープ時間は100秒ではなく1500msでした。WinAPIのスリープ()関数呼び出しは

これは一般的な動作ですか、私のMOBO、CPU、Windowsのインストールで間違っていることを念頭に置いてください。

編集:可能であれば、このコードを実行してスリープ時間の長さを通知することができます。私は私の友人にこれを実行させ、彼は実際にそれをすべて1msで持っていました。

#include <iostream> 
#include <ctime> 
#include <Windows.h> 

void test(void) 
{ 
    std::cout << "Testing 1ms sleep." << std::endl; 

    for (unsigned int i = 0; i < 10; i++) 
    { 
     std::clock_t startClocks = std::clock(); 

     Sleep(1); 

     std::clock_t clocksTaken = std::clock() - startClocks; 
     std::cout << "Time: " << clocksTaken << "ms." << std::endl; 
    } 
} 

int main(void) 
{ 
    test(); 

    std::cin.sync(); 
    std::cin.get(); 
    return 0; 
} 

EDIT2:一部の人が1ミリ秒を取得している理由はいくつかの他のプログラムは、1ミリ秒にシステム全体のタイマーの分解能を設定している実行していることであるようです。デフォルトでは、Windows 7では15.6msになるはずです。

+0

で見つけることができる(ハードウェア/それが実行されている、その時のプロセッサの負荷など)私はあなたがそのコードを実行するように人々に求めて達成することを望んでいるか分からない。ループが繰り返されるたびに、ループが実行されるたびに異なる時間を出力することは、完全に可能です。 – obmarg

+0

私はSleep()がWindows上でハードウェア固有であるとは思わない。 timeBeginPeriod()を使用するプログラムを実行していない場合、結果は15-16msでなければなりません。例:Windows Media Playerは10msに設定し、BSPlayerは1msに設定します。また、一部のブラウザで調整されているとも言われています。 – NFRCR

+0

おそらく直接接続されていないかもしれませんが、依然として間接的なリンクが存在する可能性があります。大量の電力不足のマシンでウィンドウを実行していると、負荷が上がり、スリープ復帰までの時間も長くなります。 – obmarg

答えて

7

ことがある。この共通の動作

です。

ウィンドウのスレッドスケジューラは、時間の量子で動作します(正確な長さは、Windowsのバージョンとエディションを含むさまざまな要因によって異なります)。事実上、ゼロ以外の遅延は、完全な量子に切り上げられます。

+0

@MatteoItaliaこれ以上の優先度で実行できるものがない場合、ゼロスリープはすぐに戻ります。ブロックされないことがあります。非ゼロ値では、私が理解するように、常にいくつかのブロックが存在します。 – Richard

+0

正しい、削除してください。 –

0

(デバッグまたはリリースビルド)

どのように遅延を測定していますか?正確な方法を使用していますか? (クエリパフォーマンスカウンタ)

私は正確なタイミングのためにWindows OSに頼るべきではないと思います。それはリアルタイムオペレーティングシステムではなく、プロセスから時間を奪う外部の「力」が存在します。

11

スリープにより、指定されたタイムアウトより長くスリープする可能性がありますが、スレッドは少なくともその時間だけスリープすることが保証されます。 documentationから

スリープ間隔が経過した後、スレッドを実行する準備ができています。 0ミリ秒を指定すると、スレッドはタイムスライスの残りの部分を放棄しますが、準備ができたままになります。 レディスレッドはすぐに実行されることは保証されません。したがって、スレッドは、スリープインターバルが経過してからしばらくするまで実行されないことがあります。詳細については、Scheduling Prioritiesを参照してください。

1

ほとんどのクロックの分解能は約10〜15ミリ秒であるように、これは、かなり正常な動作です。したがって、クロック解像度(あなたの場合は1)よりも小さい値で呼び出すと、少なくとも1クロックサイクルの間待たなければならない可能性が高くなります。なぜなら、それはあなたが望む時間より長くスリープするからです。

一般に、これらの問題のためにこのような精度が必要なものには、スリープを使用しないでください。

2

Windowsでのタイミングに関して私が見つけたベスト記事は、herehereです。有用な点は、一度マルチメディアタイマーの解像度を変更すると(たとえば、timeBeginPeriod(1)が1ms)、それは一般にスケジューラに影響するため、スリープコマンドにも影響します。 これは、非リアルタイムのOSでは1msの精度を実現することは不可能であると述べています。

1

動作は問題ありません。基本的なハードウェア、OSのバージョン、さらにはソフトウェアを実行していても、sleep()関数に関してOSの習慣に影響を与えています( )。

システム割り込み時間よりも短いdwMillisecondsでスリープが呼び出された場合、呼び出しは次の割り込み時に戻ります。このようにして、実際の遅延はスリープが(割り込み期間に関して)呼び出された時間に依存する。

スリープ(1)が必要な場合は、マルチメディアタイマインタフェースを使用して、ハードウェアがサポートする最大限の割り込み周波数にすることをお勧めします。スリープ容易様々な要因に応じて異なる時間がかかることがあるので

スリープ()関数、待機可能タイマ機能、タイマー分解能、及びマルチメディアタイマーの設定についての詳細な概要はWindows Timestamp Project

関連する問題