60 votes

Dormir moins d'une milliseconde

Sur Windows, vous avez un problème vous généralement de ne jamais rencontrer sur Unix. Qui est de savoir comment obtenir un fil de dormir pour moins d'une milliseconde. Sur Unix, vous avez généralement un certain nombre de choix (sommeil, usleep et nanosleep) pour s'adapter à vos besoins. Sur Windows, cependant, il y a seulement Dormir avec la granularité de l'ordre de la milliseconde. Vous pouvez, toutefois, utiliser l' select appel système pour créer une microseconde de sommeil. Sur Unix, c'est assez simple:

int usleep(long usec)
{
    struct timeval tv;
    tv.tv_sec = usec/1000000L;
    tv.tv_usec = usec%1000000L;
    return select(0, 0, 0, 0, &tv);
}

Sur Windows, cependant, l'utilisation de l' select vous oblige à inclure le Winsock bibliothèque qui doit être initialisé comme ceci dans votre application:

WORD wVersionRequested = MAKEWORD(1,0);
WSADATA wsaData;
WSAStartup(wVersionRequested, &wsaData);

Puis sélectionnez, ne vous permettra pas d'être appelé sans prise de sorte que vous avez à faire un peu plus pour créer un microsleep méthode:

int usleep(long usec)
{
    struct timeval tv;
    fd_set dummy;
    SOCKET s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    FD_ZERO(&dummy);
    FD_SET(s, &dummy);
    tv.tv_sec = usec/1000000L;
    tv.tv_usec = usec%1000000L;
    return select(0, 0, 0, &dummy, &tv);
}

Tout cela a créé usleep méthodes renvoie zéro en cas de succès et de non-zéro pour les erreurs.

89voto

Joel Coehoorn Points 190579

Cela indique une mauvaise compréhension des fonctions du sommeil. Le paramètre que vous passer un minimum de temps pour dormir. Il n'y a aucune garantie que le fil va se réveiller exactement après le délai spécifié. En fait, les threads ne pas "réveiller" à tout, mais sont plutôt choisis pour l'exécution par le planificateur. Le planificateur peut choisir d'attendre beaucoup plus longtemps que la demande de la durée du sommeil pour activer un fil, surtout si un autre thread est toujours actif à ce moment.

49voto

Will Dean Points 25866

Comme Joel dit, vous ne pouvez pas véritablement à la mode "veille" (c'est à dire renoncer à la date prévue de votre CPU) pour de courtes périodes. Si vous souhaitez retarder pour quelque peu de temps, alors vous avez besoin de tourner, de la vérification à plusieurs reprises un appareil de haute résolution de la minuterie (par exemple, le rendement de la minuterie') et en espérant que quelque chose de prioritaire de ne pas préjuger de vous de toute façon.

Si vous vous souciez vraiment de délais précis de ces brefs moments, vous ne devriez pas être à l'aide de Windows.

35voto

Joe Schneider Points 3563

Utiliser les minuteurs de haute résolution disponible dans winmm.lib. Voir ce pour un exemple.

11voto

darron Points 2331

Oui, vous avez besoin de comprendre votre système d'exploitation temps des quantums. Sur Windows, vous n'aurez même pas obtenir 1 ms temps de résolution, sauf si vous modifiez le quantum de temps de 1ms. (En utilisant par exemple timeBeginPeriod()/timeEndPeriod()) Qui ne seront toujours pas vraiment quoi que ce soit garantie. Encore un peu de charge ou d'une seule de merde pilote de périphérique de jeter le tout hors tension.

SetThreadPriority() est utile, mais est très dangereux. Mauvais pilotes de périphérique pouvez toujours vous ruiner.

Vous avez besoin d'un ultra-contrôlé environnement informatique pour faire ce vilain truc du travail à tous.

5voto

user16523 Points 51

Si vous voulez tellement granularité vous êtes au mauvais endroit (dans l'espace utilisateur). N'oubliez pas que si vous êtes dans l'espace utilisateur de votre temps n'est pas toujours précis. Le planificateur peut démarrer votre thread (ou application) et à l'annexe il, vous êtes donc en fonction de l'OS du planificateur . Si vous êtes à la recherche de quelque chose précisément, vous avez à faire: 1) Dans l'espace noyau (comme les pilotes) 2) Choisissez un RTOS. De toute façon si vous êtes à la recherche pour certains de granularité (mais n'oubliez pas le problème de l'espace utilisateur ) chercher à Fonction QueryPerformanceCounter et QueryPerformanceFrequency fonction dans MSDN.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X