2012-03-01 4 views
8

OS: Windows 7WinAPI sonno() chiamata di funzione dorme più a lungo del previsto

Quando si chiama la funzione WinAPI sonno() come Sonno (1) il filo in realtà dorme per 15ms. L'ho fatto 100 volte in un ciclo e il tempo di sospensione totale era 1500ms invece di 100.

È questo comportamento comune o devo essere incentrato su qualcosa che non va con il mio MOBO, CPU, installazione di Windows?

MODIFICA: se possibile, è possibile eseguire questo codice e pubblicare per quanto tempo è stato il periodo di sospensione. Lascio che un mio amico lo faccia, e in realtà ha avuto tutto a 1 ms.

#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: Sembra che il motivo per cui alcune persone stanno ottenendo 1ms è che qualche altro programma è in esecuzione che imposta la risoluzione del timer a livello di sistema a 1ms. Per impostazione predefinita, dovrebbe essere 15.6ms su Windows 7.

+0

Dal sonno può facilmente prendere un orario diverso a seconda di vari fattori (l'hardware/sto funzionando, il carico del processore in quel momento ecc.) Non sono sicuro di cosa speri di ottenere chiedendo alle persone di eseguire quel codice. Sarebbe perfettamente possibile che emetta un tempo diverso per ogni iterazione del ciclo, ogni volta che viene eseguito. – obmarg

+0

Non penso che Sleep() sia specifico dell'hardware su Windows. Se non utilizzi programmi che utilizzano timeBeginPeriod(), i risultati dovrebbero essere 15-16ms. Ad esempio: Windows Media Player lo imposta su 10 ms e BSPlayer su 1 ms. È stato anche detto che alcuni browser lo regolano. – NFRCR

+0

Forse non è collegato direttamente, ma potrebbe esserci comunque un collegamento indiretto: se stai usando Windows su una macchina molto sottodimensionata, il carico salirà e potrebbe anche passare il tempo prima che il sonno ritorni. – obmarg

risposta

7

È questo il comportamento comune

È.

Lo scheduler della finestra funziona su un quantum temporale (la lunghezza esatta dipende da vari fattori tra cui la versione e l'edizione di Windows). In effetti qualsiasi ritardo diverso da zero viene arrotondato a un quantum completo.

+0

@MatteoItalia A zero il sonno tornerà immediatamente se non c'è nient'altro disponibile per l'esecuzione (con questa o priorità più alta): potrebbe non bloccarsi del tutto. Con un valore diverso da zero, a quanto ho capito, ci sarà sempre un blocco. – Richard

+0

correggere, eliminare. –

0

(debug o rilasciare costruire?)

Come stai misurando il ritardo? stai usando un metodo preciso? (queryperformancecounter)

Non penso che dovresti fare affidamento sul sistema operativo Windows per una sincronizzazione accurata; non è un sistema operativo in tempo reale e ci saranno "forze" esterne che ruberanno tempo al tuo processo.

11

Lo stato di sospensione può far dormire il thread per un periodo di tempo superiore rispetto al timeout specificato, garantisce solo che il thread dorma per almeno quel lasso di tempo.

Dal documentation:

Trascorso il tempo di sonno è passato, il filo è pronto a funzionare. Se si specifica 0 millisecondi, il thread rinuncerà al resto del suo intervallo temporale ma resterà pronto. Si noti che non è garantito che un thread pronto venga eseguito immediatamente. Di conseguenza, il thread potrebbe non funzionare fino a qualche tempo dopo l'intervallo di sospensione. Per ulteriori informazioni, vedere Scheduling Priorities.

1

Questo è un comportamento abbastanza normale, come la maggior parte delle risoluzioni di clock sono circa 10-15 ms. Pertanto, se lo chiami con un valore inferiore alla risoluzione dell'orologio (nel tuo caso, 1), probabilmente dovrà aspettare almeno un ciclo di clock, motivo per cui dorme più a lungo di quanto tu voglia.

In genere, non utilizzare Sleep per cose che richiedono tale precisione a causa di questi problemi.

2

I migliori articoli che ho trovato per quanto riguarda i tempi su Windows sono here e here. La parte utile è che una volta modificata la risoluzione del timer multimediale (ad esempio timeBeginPeriod(1) per 1 ms) influisce anche sul comando di sospensione, poiché influisce sullo scheduler in generale. Detto questo, la precisione di 1 ms non è possibile su un sistema operativo non in tempo reale.

1

Il comportamento è OK. L'hardware sottostante, la versione del sistema operativo e persino il software in esecuzione influenzano lo l'abitudine del sistema operativo rispetto alla funzione sleep().

Se viene chiamato uno sleep con dwMilliseconds inferiore al periodo di interrupt di sistema, la chiamata ritornerà al successivo interrupt. In questo modo il ritardo effettivo dipende dal momento in cui è stato chiamato il sonno (rispetto al periodo di interruzione).

Si consiglia di utilizzare l'interfaccia del timer multimediale per aumentare la frequenza di interruzione al massimo supportato dall'hardware, quando si desidera una sospensione (1).

Una panoramica dettagliata sulla funzione sleep(), le funzioni di timer waitable, le risoluzioni del timer, e le impostazioni del timer multimediali si possono trovare presso il Windows Timestamp Project

Problemi correlati