Dormi per millisecondi


632

So che la sleep(x)funzione POSIX fa dormire il programma per x secondi. Esiste una funzione per far dormire il programma per x millisecondi in C ++?


7
Dovresti essere consapevole che, in Windows comunque, Sleep()ha una precisione di millisecondi , ma la sua accuratezza può essere ordini di grandezza superiori. Potresti pensare di dormire per 4 millisecondi, ma in realtà dormire per 400.
John Dibling,

5
@ John Dibling: Penso che stia usando POSIX sleep, non win32 Sleepdati "x secondi".
CB Bailey,

1
Sebbene C e C ++ abbiano una diversa manipolazione dei nomi, che può essere una fonte di bug e incompatibilità, nella maggior parte dei casi è bene usare le intestazioni C in C ++. Tuttavia, se vuoi essere assolutamente sicuro che nulla vada storto, #includel'intestazione C all'interno di un extern "C" {}blocco. Inoltre, se si hanno file di origine C e C ++ nello stesso progetto, si consiglia vivamente di farlo per evitare problemi, soprattutto se si includono le stesse intestazioni in entrambi i tipi di file di origine (nel qual caso è necessario) . Se hai un progetto puramente C ++, potrebbe funzionare senza alcun problema.
adam10603,

2
@JohnDibling no, non 400ms. La peggiore precisione che avresti mai potuto ottenere era da Windows 9x, con GetTickCountuna risoluzione di 55 ms; le versioni successive avevano una risoluzione di 16ms o meno. Un utente ha pensato di ottenere una risoluzione di 16 ms da Sleep, ma ha riferito che Sleepera abbastanza preciso e che l'apparente imprecisione era causata dall'uso GetTickCountper misurare il passare del tempo.
Qwertie,

Risposte:


457

Nota che non esiste un'API C standard per i millisecondi, quindi (su Unix) dovrai accontentarti usleep, che accetta i microsecondi:

#include <unistd.h>

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

2
È un sonno frenetico? Ho bisogno di cedere a un altro thread durante il sonno; posso usare usleepper quello?
Michael,

13
Non è un'attesa impegnata stackoverflow.com/a/8156644/1206499 e nanosleeppotrebbe essere una scelta migliore poiché usleepè obsoleta.
jswetzen,

4
Niet, per favore considera di menzionare la risposta di @ HighCommander4 che è più portabile se hai un compilatore C ++ 11.
einpoklum,

6
usleep () deprecato in POSIX nel 2001 e rimosso nel 2008.
Jetski S-type

1271

In C ++ 11, puoi farlo con le funzionalità di libreria standard:

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

Chiaro e leggibile, non è più necessario indovinare quali unità sleep()prende la funzione.


6
Std :: this_thread :: sleep_for definisce un punto di interruzione? Come boost :: this_thread_sleep fa?
Martin Meeser,

73
Questo è il modo giusto per farlo. Periodo. Il thread è multipiattaforma e crono.
Vuoto il

88
@Void. Un ottimo modo certamente, ma "il" e "periodo" sono parole terribilmente forti.
Fisico pazzo,

5
È un sonno frenetico? Ho bisogno di cedere a un altro thread durante il sonno; posso usare sleep_forper quello?
Michael,

14
@Michael: Non è un sonno indaffarato, cederà ad altri thread.
HighCommander4,

83

Per rimanere portatile puoi usare Boost :: Thread per dormire:

#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;
}

Questa risposta è un duplicato ed è stata pubblicata in questa domanda in precedenza. Forse potresti trovare alcune risposte utilizzabili anche lì.


6
Tieni presente che, in un ambiente multi-thread, boost::this_thread::sleepaggiunge un punto di interruzione al codice. boost.org/doc/libs/1_49_0/doc/html/thread/…
Martin Meeser,

35

In Unix puoi usare usleep .

In Windows c'è Sleep .


4
e la chiamata di Windows è in millisecondi.
shindigo,

17
Devi includere <unistd.h> o <Windows.h> rispettivamente.
gbmhunter

Sì, ma la risoluzione temporale effettiva non può essere 15-16 ms (anche se l'unità nella chiamata è 1 ms) e quindi il tempo minimo è 15-16 ms?
Peter Mortensen,

33

A seconda della piattaforma che potresti avere usleepo nanosleepdisponibile. usleepè obsoleto ed è stato eliminato dal più recente standard POSIX; nanosleepè preferito.


6
Si noti che while usleep()è dichiarato in <unistd.h>, confusamente, nanosleep()è dichiarato in <time.h>/ <ctime>.
gbmhunter

27

Perché non usare la libreria time.h? Funziona su sistemi Windows e POSIX:

#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;
}

Codice corretto: ora la CPU rimane nello stato IDLE [2014.05.24]:

#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
Uno dei problemi con quel codice è che si tratta di un circuito occupato, che continuerà a utilizzare il 100% di un singolo core del processore. La funzione sleep è implementata attorno a una chiamata del sistema operativo che metterà in sleep il thread corrente e farà qualcos'altro, e si riattiverà il thread solo allo scadere del tempo specificato.
Ismael,

Hai ragione: consumerà il 100% di un core di una CPU. Quindi ecco il codice riscritto usando le funzioni di
sospensione del

@BartGrzybicki So che questa è una vecchia risposta e tutto, ma in Visual Studio 2017 su una macchina Windows, #ifdef WIN32non viene valutata come vera per impostazione predefinita.
kayleeFrye_onDeck il

2
@kayleeFrye_onDeck Il codice è errato. Dovrebbe essere #ifdef _WIN32.
Contango,

1
@Contango Lo sapevo! Ma non quando l'ho scritto ... lol. Grazie per il follow-up!
kayleeFrye_onDeck,

17

nanosleepè una scelta migliore di usleep- è più resistente agli interrupt.


6
Conoscevo usleep, ma no nanosleep. Dovresti fornire un esempio di utilizzo su Linux.
jww


7

Se si utilizza MS Visual C ++ 10.0, è possibile farlo con le funzionalità di libreria standard:

Concurrency::wait(milliseconds);

avrai bisogno:

#include <concrt.h>

10
Non usare la parola "standard" quando in realtà non lo intendi. non<concrt.h> è un'intestazione della libreria standard - può essere una libreria della piattaforma; nel qual caso dovresti indicare chiaramente i prerequisiti.
Toby Speight,

5

Su piattaforme con la selectfunzione (POSIX, Linux e Windows) puoi fare:

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.
    }
}

Tuttavia, al giorno d'oggi ci sono alternative migliori disponibili.


Non riesco a compilare in VS2017 su un computer Windows:error LNK2019: unresolved external symbol _select@20 referenced in function "void __cdecl sleep(unsigned long)" (?sleep@@YAXK@Z)
kayleeFrye_onDeck

@kayleeFrye_onDeck Compila. Semplicemente non collega. Cerca documenti di Windows.
Maxim Egorushkin,

quale intestazione usi per timeval ??
Totte Karlsson

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

4

Il modo di dormire il programma in C ++ è il Sleep(int)metodo. Il file di intestazione è#include "windows.h."

Per esempio:

#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;
}

Il tempo che dorme è misurato in millisecondi e non ha limiti.

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

3
Cosa vuoi dire che non ha limiti? Ha sicuramente un limite che è 0xFFFFFFFE. L'attesa di 0xFFFFFFFF semplicemente non scade (il che significa che attenderà fino alla fine del programma).
Izzy,

Non intendevo in quel modo Izzy, scusate per il nostro malinteso. Volevo dire che puoi inserire qualsiasi numero positivo di millisecondi. Quindi aspetterà che molti millisecondi chiudano il programma. Se non capisci, ti preghiamo di dirlo, ti spiegherò di più.
Phi il

Sì, ma qual è la risoluzione temporale effettiva? Non potrebbe essere 15-16 ms in alcuni casi? Ad esempio, se usi Sleep (3) dormirà effettivamente per 3 ms o sarà invece 15-16 ms?
Peter Mortensen,

3

Seleziona chiamata è un modo per avere più precisione (il tempo di sonno può essere specificato in nanosecondi).


Mentre questo potrebbe essere un valido suggerimento per risolvere il problema, una buona risposta dimostra anche la soluzione. Si prega di modificare per fornire codice di esempio per mostrare quello che vuoi dire. In alternativa, considera invece di scrivere questo come commento.
Toby Speight,

3

Usa Boost thread di input / output asincroni, sleep per x millisecondi;

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

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

Cosa accadrà effettivamente se provi a dormire per 3 millisecondi? Saranno invece 15-16 millisecondi? L'hai misurato?
Peter Mortensen,

1

La domanda è vecchia, ma sono riuscito a capire un modo semplice per avere questo nella mia app. Puoi creare una macro C / C ++ come mostrato di seguito e usarla:

#ifndef MACROS_H
#define MACROS_H

#include <unistd.h>

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

#endif // MACROS_H

1

Da C ++ 14 usando std e anche i suoi letterali numerici:

#include <chrono>
#include <thread>

using namespace std::chrono;

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

0

In sostituzione di Win32 per i sistemi POSIX:

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

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

Preferisco nanosleep()a usleep(): quest'ultimo è deprecato ed è stato eliminato dalla recente norma più POSIX.
Toby Speight,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.