2014-05-04 30 views
4

Sleep on Windows 8.1 x64總是會比需要多持續1毫秒。例如,Sleep(1)持續大約2毫秒,Sleep(2)-3等timeBeginPeriod設置爲1.在Windows 7工作正常(沒有超過毫秒)。這種行爲是否正常/可以解決?Windows 8(.1)睡眠比需要多1 ms

#include <Windows.h> 
#include <stdio.h> 

#pragma comment(lib, "winmm.lib") 

LARGE_INTEGER Frequency; 

long long int GetCurrent() 
{ 
    LARGE_INTEGER counter; 

    QueryPerformanceCounter(&counter); 

    return (1000000 * counter.QuadPart/Frequency.QuadPart); 
} 

int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 
{ 
    timeBeginPeriod(1); 

    QueryPerformanceFrequency(&Frequency); 

    const unsigned int count = 1000; 

    long long int buffer[count]; 

    long long int lastTime = GetCurrent(), currentTime; 

    for (unsigned int i = 0; i < count; i++) 
    { 
     currentTime = GetCurrent(); 

     buffer[i] = currentTime - lastTime; 

     lastTime = currentTime; 

     Sleep(1); 
    } 

    timeEndPeriod(1); 

    FILE *file = fopen("log.txt", "w"); 

    for (unsigned int i = 0; i < count; i++) 
     fprintf(file, "%ld\n", buffer[i]); 

    fclose(file); 

    return EXIT_SUCCESS; 
} 
+7

'睡眠'保證你至少* *睡眠時間你問,可能更多,在調度程序的奇想;它一直都是這樣的,你不能依靠它來精確地測量,尤其是在它的頻譜的低端。 –

+0

我明白這一點,但在'Windows 7'上(可能在其他系統上),平均設置'timeBeginPeriod'的'Sleep'是近似請求的值。但在Windows 8.1上,它總是增加+1多餘的ms。我認爲這種行爲很奇怪。 – Demion

+9

定時器在Windows 8.1中進行修飾。我用這個代碼得到1毫秒和2毫秒間隔的混合包,如果可以無限調用Sleep(),它會更好。這不是卡片。有時丟失1毫秒是[記錄的行爲](http://msdn.microsoft.com/en-us/library/windows/hardware/dn265247%28v=vs.85%29.aspx)。使用實際的計時器而不是依賴Sleep(),因此Windows可以正確執行此操作。 timeSetEvent()是遺留的,CreateTimerQueueTimer()是現代的。 –

回答

0

NtDelayExecution解決方法由於邁赫達德

static NTSTATUS (__stdcall *NtDelayExecution)(BOOL Alertable, PLARGE_INTEGER DelayInterval) = (NTSTATUS (__stdcall*)(BOOL, PLARGE_INTEGER)) GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtDelayExecution"); 

LARGE_INTEGER delay; 

unsigned int milliseconds = 1; 

delay.QuadPart = (milliseconds > 1) ? -10000LL * (milliseconds - 1) : -1LL; 

NtDelayExecution(false, &delay);