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 ?

Prasanth Madhavan
quelle
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);
Niet the Dark Absol
quelle
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.

HighCommander4
quelle
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.

MOnsDaR
quelle
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 .

INS
quelle
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.

CB Bailey
quelle
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;
}
Bart Grzybicki
quelle
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.

Johan Kotlinski
quelle
6
Ich war vertraut mit usleep, aber nicht nanosleep. Sie sollten ein Beispiel für die Verwendung unter Linux angeben.
JWW
14
#include <windows.h>

Syntax:

Sleep (  __in DWORD dwMilliseconds   );

Verwendungszweck:

Sleep (1000); //Sleeps for 1000 ms or 1 sec
foobar
quelle
3
Was müssen Sie dazu hinzufügen?
ʇolɐǝz ǝɥʇ qoq
#include <WinBase.h>
Foobar
7
Nein, Sie müssen#include <windows.h>
ʇolɐǝz ǝɥʇ qoq
7
Die Frage impliziert stark, dass eine POSIX-Lösung erforderlich ist.
Toby Speight
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>
Metronit
quelle
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.

Maxim Egorushkin
quelle
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
Phi
quelle
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).

Madhava Gaikwad
quelle
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));
Anum Sheraz
quelle
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
VPZ
quelle
1

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

#include <chrono>
#include <thread>

using namespace std::chrono;

std::this_thread::sleep_for(123ms);
Martin Flaska
quelle
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
}
lama12345
quelle
Bevorzugen nanosleep()an usleep(): Letztere ist veraltet und hat sich von der jüngsten POSIX - Standard gelöscht.
Toby Speight