Millisekunden schlafen


631

Ich weiß, dass die POSIX- sleep(x)Funktion das Programm für x Sekunden in den Ruhezustand versetzt. Gibt es eine Funktion, mit der das Programm in C ++ für x Millisekunden in den Ruhezustand versetzt wird ?


7
Sie sollten sich bewusst sein , dass in Windows wie auch immer, Sleep()Millisekunde hat Präzision , aber es ist die Genauigkeit kann um Größenordnungen höher sein. Sie können denken, Sie schlafen für 4 Millisekunden, aber tatsächlich für 400 schlafen.
John Dibling

5
@ John Dibling: Ich denke, er verwendet POSIX sleep, nicht win32 Sleepmit "x Sekunden".
CB Bailey

1
Obwohl C und C ++ unterschiedliche Namen haben, was zu Fehlern und Inkompatibilitäten führen kann, ist es in den meisten Fällen in Ordnung, C-Header in C ++ zu verwenden. Wenn Sie jedoch absolut sicher sein möchten, dass nichts schief geht, befindet sich #includeder C-Header in einem extern "C" {}Block. Wenn Sie C- und C ++ - Quelldateien im selben Projekt haben, wird dringend empfohlen, dies zu tun, um Probleme zu vermeiden, insbesondere wenn Sie dieselben Header in beide Arten von Quelldateien einfügen (in diesem Fall ist dies erforderlich). . Wenn Sie ein reines C ++ - Projekt haben, funktioniert es möglicherweise überhaupt nicht.
Adam10603

2
@ JohnDibling nein, nicht 400ms. Die schlechteste Präzision, die Sie jemals bekommen haben könnten, war Windows 9x GetTickCountmit einer Auflösung von 55 ms. spätere Versionen hatten eine Auflösung von 16 ms oder weniger. Ein Benutzer dachte, er würde eine Auflösung von 16 ms aus dem Schlaf erhalten , berichtete dann aber, dass er Sleepselbst ziemlich genau sei und die offensichtliche Ungenauigkeit durch die GetTickCountMessung des Zeitablaufs verursacht wurde.
Qwertie

Antworten:


457

Beachten Sie, dass es keine Standard-C-API für Millisekunden gibt. Sie müssen sich also (unter Unix) damit zufrieden geben usleep, was Mikrosekunden akzeptiert:

#include <unistd.h>

unsigned int microseconds;
...
usleep(microseconds);

2
Ist es ein geschäftiger Schlaf? Ich muss mich im Schlaf einem anderen Faden ergeben. kann ich dafür verwenden usleep?
Michael

13
Es ist keine geschäftige Wartezeit stackoverflow.com/a/8156644/1206499 und nanosleepkann eine bessere Wahl sein, da usleepes veraltet ist.
jswetzen

4
Niet, bitte erwägen Sie, die Antwort von @ HighCommander4 zu erwähnen, die portabler ist, wenn Sie einen C ++ 11-Compiler haben.
Einpoklum

6
usleep () war 2001 in POSIX veraltet und wurde 2008 entfernt.
Jetski S-type

1270

In C ++ 11 können Sie dies mit Standardbibliotheksfunktionen tun:

#include <chrono>
#include <thread>
std::this_thread::sleep_for(std::chrono::milliseconds(x));

Klar und lesbar, Sie müssen nicht mehr raten, welche Einheiten die sleep()Funktion benötigt.


6
Definiert std :: this_thread :: sleep_for einen Unterbrechungspunkt? Wie boost :: this_thread_sleep tut?
Martin Meeser

73
Dies ist der richtige Weg. Zeitraum. Thread ist plattformübergreifend sowie chrono.
Nichtig

88
@Leere. Ein sehr guter Weg sicherlich, aber "die" und "Periode" sind schrecklich starke Worte.
Verrückter Physiker

5
Ist es ein geschäftiger Schlaf? Ich muss mich im Schlaf einem anderen Faden ergeben. kann ich benutzensleep_for ?
Michael

14
@ Michael: Es ist kein geschäftiger Schlaf, es wird anderen Threads nachgeben.
HighCommander4

83

Um tragbar zu bleiben, können Sie Boost :: Thread zum Schlafen verwenden:

#include <boost/thread/thread.hpp>

int main()
{
    //waits 2 seconds
    boost::this_thread::sleep( boost::posix_time::seconds(1) );
    boost::this_thread::sleep( boost::posix_time::milliseconds(1000) );

    return 0;
}

Diese Antwort ist ein Duplikat und wurde bereits in dieser Frage veröffentlicht . Vielleicht könnten Sie dort auch einige brauchbare Antworten finden.


6
Beachten Sie, dass in einer Umgebung mit mehreren Threads boost::this_thread::sleepIhrem Code ein Unterbrechungspunkt hinzugefügt wird. boost.org/doc/libs/1_49_0/doc/html/thread/…
Martin Meeser

35

Unter Unix können Sie usleep verwenden .

In Windows gibt es Schlaf .


4
und der Windows-Aufruf erfolgt in Millisekunden.
Shindigo

17
Sie müssen <unistd.h> bzw. <Windows.h> einschließen.
Gbmhunter

Ja, aber konnte die tatsächliche Zeitauflösung nicht 15-16 ms betragen (selbst wenn die Einheit im Anruf 1 ms beträgt) und somit die Mindestzeit 15-16 ms betragen?
Peter Mortensen

33

Abhängig von Ihrer Plattform haben Sie möglicherweise usleepoder nanosleepverfügbar. usleepist veraltet und wurde aus dem neuesten POSIX-Standard gelöscht; nanosleepIst bevorzugt.


6
Beachten Sie, dass while usleep()in <unistd.h>verwirrenderweise nanosleep()in <time.h>/ deklariert wird <ctime>.
Gbmhunter

27

Warum nicht die time.h Bibliothek benutzen? Läuft auf Windows- und POSIX-Systemen:

#include <iostream>
#include <time.h>

using namespace std;

void sleepcp(int milliseconds);

void sleepcp(int milliseconds) // Cross-platform sleep function
{
    clock_t time_end;
    time_end = clock() + milliseconds * CLOCKS_PER_SEC/1000;
    while (clock() < time_end)
    {
    }
}
int main()
{
    cout << "Hi! At the count to 3, I'll die! :)" << endl;
    sleepcp(3000);
    cout << "urrrrggghhhh!" << endl;
}

Korrigierter Code - CPU bleibt jetzt im IDLE-Status [24.05.2014]:

#include <iostream>
#ifdef _WIN32
    #include <windows.h>
#else
    #include <unistd.h>
#endif // _WIN32

using namespace std;

void sleepcp(int milliseconds);

void sleepcp(int milliseconds) // Cross-platform sleep function
{
    #ifdef _WIN32
        Sleep(milliseconds);
    #else
        usleep(milliseconds * 1000);
    #endif // _WIN32
}
int main()
{
    cout << "Hi! At the count to 3, I'll die! :)" << endl;
    sleepcp(3000);
    cout << "urrrrggghhhh!" << endl;
}

24
Eines der Probleme mit diesem Code besteht darin, dass es sich um eine Besetztschleife handelt, die weiterhin 100% eines einzelnen Prozessorkerns verwendet. Die Sleep-Funktion wird um einen Betriebssystemaufruf herum implementiert, der den aktuellen Thread in den Ruhezustand versetzt und etwas anderes ausführt und den Thread erst nach Ablauf der angegebenen Zeit aufweckt.
Ismael

Sie haben Recht - es wird 100% eines Kerns mit einer CPU verbrauchen. Also hier ist Code mit Systemschlaffunktionen umgeschrieben - und es ist immer noch plattformübergreifend:
Bart Grzybicki

@BartGrzybicki Ich weiß, dass dies eine alte Antwort ist, aber in Visual Studio 2017 auf einem Windows-Computer wird #ifdef WIN32standardmäßig nicht als wahr ausgewertet.
KayleeFrye_onDeck

2
@kayleeFrye_onDeck Code ist falsch. Es sollte sein #ifdef _WIN32.
Contango

1
@ Contango das wusste ich! Aber nicht als ich das schrieb ... lol. Vielen Dank für das Follow-up!
KayleeFrye_onDeck

17

nanosleepist eine bessere Wahl als usleep- es ist widerstandsfähiger gegen Interrupts.


6
Ich war vertraut mit usleep, aber nicht nanosleep. Sie sollten ein Beispiel für die Verwendung unter Linux angeben.
JWW


7

Wenn Sie MS Visual C ++ 10.0 verwenden, können Sie dies mit Standardbibliotheksfunktionen tun:

Concurrency::wait(milliseconds);

du wirst brauchen:

#include <concrt.h>

10
Verwenden Sie das Wort "Standard" nicht, wenn Sie es nicht wirklich meinen. <concrt.h>ist kein Standardbibliotheksheader - es kann sich um eine Plattformbibliothek handeln; In diesem Fall sollten Sie die Voraussetzungen klar angeben.
Toby Speight

5

Auf Plattformen mit der selectFunktion (POSIX, Linux und Windows) können Sie Folgendes tun:

void sleep(unsigned long msec) {
    timeval delay = {msec / 1000, msec % 1000 * 1000};
    int rc = ::select(0, NULL, NULL, NULL, &delay);
    if(-1 == rc) {
        // Handle signals by continuing to sleep or return immediately.
    }
}

Heutzutage gibt es jedoch bessere Alternativen.


Kann nicht scheinen, in VS2017 auf einem Windows-Computer zu kompilieren:error LNK2019: unresolved external symbol _select@20 referenced in function "void __cdecl sleep(unsigned long)" (?sleep@@YAXK@Z)
kayleeFrye_onDeck

@kayleeFrye_onDeck Es wird kompiliert. Verlinkt einfach nicht. Suchen Sie nach Windows-Dokumenten.
Maxim Egorushkin

Welchen Header verwenden Sie für Timeval?
Totte Karlsson vor

@TotteKarlsson <sys/time.h>.
Maxim Egorushkin

4

Der Weg, um Ihr Programm in C ++ zu schlafen, ist die Sleep(int)Methode. Die Header-Datei dafür ist#include "windows.h."

Zum Beispiel:

#include "stdafx.h"
#include "windows.h"
#include "iostream"
using namespace std;

int main()
{
    int x = 6000;
    Sleep(x);
    cout << "6 seconds have passed" << endl;
    return 0;
}

Die Schlafzeit wird in Millisekunden gemessen und ist unbegrenzt.

Second = 1000 milliseconds
Minute = 60000 milliseconds
Hour = 3600000 milliseconds

3
Was meinst du damit, dass es keine Grenzen gibt? Es hat sicherlich eine Grenze, die 0xFFFFFFFE ist. Das Warten auf 0xFFFFFFFF läuft einfach nicht ab (was bedeutet, dass es bis zum Ende des Programms wartet).
Izzy

Ich habe es nicht so gemeint, Izzy, entschuldige unser Missverständnis. Ich meinte, dass Sie eine beliebige positive Anzahl von Millisekunden eingeben können. Es wird also so viele Millisekunden warten, bis das Programm geschlossen ist. Wenn Sie nicht verstehen, sagen Sie es bitte, ich werde Ihnen mehr erklären.
Phi

Ja, aber wie hoch ist die tatsächliche Zeitauflösung? Könnte es in einigen Fällen nicht 15-16 ms sein? Wenn Sie beispielsweise Sleep (3) verwenden, wird es tatsächlich 3 ms lang schlafen oder werden es stattdessen 15-16 ms sein?
Peter Mortensen

3

Mit Select Call können Sie präziser vorgehen (die Ruhezeit kann in Nanosekunden angegeben werden).


Während dies ein wertvoller Hinweis zur Lösung des Problems sein kann, zeigt eine gute Antwort auch die Lösung. Bitte bearbeiten Sie , um einen Beispielcode bereitzustellen, der zeigt, was Sie meinen. Alternativ können Sie dies stattdessen als Kommentar schreiben.
Toby Speight

3

Verwenden Sie asynchrone Eingabe- / Ausgabe-Threads von Boost und halten Sie x Millisekunden lang im Ruhezustand.

#include <boost/thread.hpp>
#include <boost/asio.hpp>

boost::thread::sleep(boost::get_system_time() + boost::posix_time::millisec(1000));

Was passiert eigentlich, wenn Sie versuchen, 3 Millisekunden zu schlafen? Werden es stattdessen 15-16 Millisekunden sein? Hast du es gemessen?
Peter Mortensen

1

Die Frage ist alt, aber ich habe es geschafft, einen einfachen Weg zu finden, dies in meiner App zu haben. Sie können ein C / C ++ - Makro wie folgt erstellen: Verwenden Sie es:

#ifndef MACROS_H
#define MACROS_H

#include <unistd.h>

#define msleep(X) usleep(X * 1000)

#endif // MACROS_H

1

Aus C ++ 14 mit std und seinen numerischen Literalen:

#include <chrono>
#include <thread>

using namespace std::chrono;

std::this_thread::sleep_for(123ms);

0

Als Win32-Ersatz für POSIX-Systeme:

void Sleep(unsigned int milliseconds) {
    usleep(milliseconds * 1000);
}

while (1) {
    printf(".");
    Sleep((unsigned int)(1000.0f/20.0f)); // 20 fps
}

Bevorzugen nanosleep()an usleep(): Letztere ist veraltet und hat sich von der jüngsten POSIX - Standard gelöscht.
Toby Speight
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.