Dormir por milissegundos

632

Eu sei que a sleep(x)função POSIX faz o programa dormir por x segundos. Existe uma função para fazer o programa dormir por x milissegundos em C ++?

Prasanth Madhavan
fonte
7
Você deve estar ciente de que, no Windows, de qualquer maneira, Sleep()tem precisão de milissegundos , mas sua precisão pode ser de magnitude superior. Você pode pensar que o seu sono para 4 milissegundos, mas na verdade dormir por 400.
John Dibling
5
@ John Dibling: Eu acho que ele está usando POSIX sleep, não win32, Sleepdado "x segundos".
CB Bailey
1
Embora C e C ++ tenham nomes diferentes, que podem ser uma fonte de bugs e incompatibilidades, na maioria dos casos é bom usar cabeçalhos C em C ++. No entanto, se você quiser ter certeza absoluta de que nada der errado, #includeo cabeçalho C dentro de um extern "C" {}bloco. Além disso, se você tiver arquivos de origem C e C ++ no mesmo projeto, é altamente recomendável fazer isso para evitar problemas, especialmente se você incluir os mesmos cabeçalhos nos dois tipos de arquivos de origem (nesse caso, isso é necessário) . Se você possui um projeto puramente em C ++, ele pode funcionar sem problemas.
adam10603
2
@JohnDibling não, não 400ms. A pior precisão que você pode ter obtido foi no Windows 9x, cuja GetTickCountresolução era de 55ms; versões posteriores tinham resolução de 16ms ou menos. Um usuário pensou que estava obtendo uma resolução de 16ms do Sleep, mas depois relatou que Sleepera bastante preciso, e a aparente imprecisão foi causada pelo uso GetTickCountpara medir a passagem do tempo.
Qwertie

Respostas:

457

Observe que não há API C padrão por milissegundos, então (no Unix) você terá que se contentar com usleep, que aceita microssegundos:

#include <unistd.h>

unsigned int microseconds;
...
usleep(microseconds);
Niet, o Escuro Absol
fonte
2
É um sono ocupado? Eu preciso ceder a outro segmento durante o sono; posso usar usleeppara isso?
Michael
13
Não é uma espera ocupada stackoverflow.com/a/8156644/1206499 e nanosleeppode ser uma escolha melhor, pois usleepestá obsoleta.
jswetzen
4
Não, considere mencionar a resposta do @ HighCommander4, que é mais portátil se você tiver um compilador C ++ 11.
Einpoklum
6
usleep () foi descontinuado no POSIX em 2001 e removido em 2008.
Jetski S-type
1271

No C ++ 11, você pode fazer isso com os recursos padrão da biblioteca:

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

Clara e legível, não há mais necessidade de adivinhar quais unidades a sleep()função leva.

HighCommander4
fonte
6
Std :: this_thread :: sleep_for define um ponto de interrupção? Como boost :: this_thread_sleep faz?
Martin Meeser
73
Este é o caminho certo para fazê-lo. Período. O segmento é multiplataforma, bem como crono.
Void
88
@Vazio. Uma maneira muito boa, certamente, mas "o" e "período" são palavras terrivelmente fortes.
Mad Physicist
5
É um sono ocupado? Eu preciso ceder a outro segmento durante o sono; posso usar sleep_forpara isso?
Michael
14
@ Michael: Não é um sono ocupado, cederá a outros tópicos.
precisa saber é o seguinte
83

Para permanecer portátil, você pode usar o Boost :: Thread para dormir:

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

Esta resposta é uma duplicata e foi postada nesta pergunta antes. Talvez você possa encontrar algumas respostas úteis também.

MOnsDaR
fonte
6
Lembre-se de que - em um ambiente multithread - boost::this_thread::sleepadiciona um ponto de interrupção ao seu código. boost.org/doc/libs/1_49_0/doc/html/thread/…
Martin Meeser
35

No Unix, você pode usar usleep .

No Windows, há suspensão .

INS
fonte
4
e a chamada do Windows está em milissegundos.
shindigo 13/09/13
17
Você deve incluir <unistd.h> ou <Windows.h> respectivamente.
Gbmhunter
Sim, mas a resolução de tempo real não pode ser de 15 a 16 ms (mesmo que a unidade na chamada seja de 1 ms) e, portanto, o tempo mínimo seja de 15 a 16 ms?
Peter Mortensen
33

Dependendo da sua plataforma, você pode ter usleepou estar nanosleepdisponível. usleepfoi descontinuado e foi excluído do padrão POSIX mais recente; nanosleepé preferível.

CB Bailey
fonte
6
Observe que while usleep()é declarado em <unistd.h>, confusamente, nanosleep()é declarado em <time.h>/ <ctime>.
Gbmhunter
27

Por que não usar a biblioteca time.h? Executa nos sistemas 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;
}

Código corrigido - agora a CPU permanece no estado 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;
}
Bart Grzybicki
fonte
24
Um dos problemas desse código é que ele é um loop ocupado, ele continuará usando 100% de um único núcleo de processador. A função de suspensão é implementada em torno de uma chamada do sistema operacional que colocará em suspensão o encadeamento atual e fará outra coisa e só ativará o encadeamento quando o tempo especificado expirar.
Ismael
Você está certo - ele consumirá 100% de um núcleo de uma CPU. Então aqui é reescrito usando funções do sono sistema - e ainda é multi-plataforma:
Bart Grzybicki
@BartGrzybicki eu sei que esta é uma resposta antiga e tudo, mas no Visual Studio 2017 em uma máquina Windows, #ifdef WIN32não é avaliada como verdadeira por padrão.
kayleeFrye_onDeck
2
@kayleeFrye_onDeck O código está errado. Deveria ser #ifdef _WIN32.
Contango 22/08/19
1
@ Contango eu sabia disso! Mas não quando eu escrevi isso ... lol. Obrigado pelo seguimento!
precisa saber é o seguinte
17

nanosleepé uma escolha melhor do que usleep- é mais resistente a interrupções.

Johan Kotlinski
fonte
6
Eu estava familiarizado usleep, mas não nanosleep. Você deve fornecer um exemplo de uso no Linux.
JWW
14
#include <windows.h>

Sintaxe:

Sleep (  __in DWORD dwMilliseconds   );

Uso:

Sleep (1000); //Sleeps for 1000 ms or 1 sec
foobar
fonte
3
O que você precisa incluir para isso?
ʇolɐǝz ǝɥʇ qoq
#include <WinBase.h>
Foobar
7
Não, você precisa ##include <windows.h>
ɐǝolɐǝz ǝɥʇ qqq 26/06
7
A questão implica fortemente que é necessária uma solução POSIX.
precisa
7

Se você estiver usando o MS Visual C ++ 10.0, poderá fazer isso com os recursos padrão da biblioteca:

Concurrency::wait(milliseconds);

você vai precisar de:

#include <concrt.h>
Metronit
fonte
10
Não use a palavra "padrão" quando não estiver falando sério. não<concrt.h> é um cabeçalho da biblioteca padrão - pode ser uma biblioteca de plataforma; nesse caso, você deve indicar claramente os pré-requisitos.
21417 Toby Speight
5

Em plataformas com a selectfunção (POSIX, Linux e Windows), você pode:

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

No entanto, existem melhores alternativas disponíveis atualmente.

Maxim Egorushkin
fonte
Parece que não consigo compilar no VS2017 em uma máquina Windows:error LNK2019: unresolved external symbol _select@20 referenced in function "void __cdecl sleep(unsigned long)" (?sleep@@YAXK@Z)
kayleeFrye_onDeck
@kayleeFrye_onDeck Compila. Apenas não vincula. Pesquise seus documentos do Windows.
Maxim Egorushkin
qual cabeçalho você usa para timeval ??
Totte Karlsson
@TotteKarlsson <sys/time.h>.
Maxim Egorushkin
4

A maneira de adormecer seu programa em C ++ é o Sleep(int)método O arquivo de cabeçalho para ele é#include "windows.h."

Por exemplo:

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

O tempo em que dorme é medido em milissegundos e não tem limite.

Second = 1000 milliseconds
Minute = 60000 milliseconds
Hour = 3600000 milliseconds
Phi
fonte
3
Como assim, não tem limite? Certamente tem um limite que é 0xFFFFFFFE. A espera de 0xFFFFFFFF simplesmente não atingirá o tempo limite (o que significa que esperará até o programa terminar).
Izzy
Eu não quis dizer isso assim Izzy, desculpe pelo nosso mal-entendido. Eu quis dizer que você pode inserir qualquer número positivo de milissegundos. Portanto, esperará muitos milissegundos para fechar o programa. Se você não entender, diga-o, explicarei mais.
Phi
Sim, mas qual é a resolução de tempo real? Não poderia ser 15-16 ms em alguns casos? Por exemplo, se você usar o Sleep (3), ele dormirá por 3 ms ou 15-16 ms?
Peter Mortensen
3

A chamada de seleção é uma maneira de ter mais precisão (o tempo de suspensão pode ser especificado em nanossegundos).

Madhava Gaikwad
fonte
Embora isso possa ser uma dica valiosa para resolver o problema, uma boa resposta também demonstra a solução. Por favor edite a fornecer exemplo de código para mostrar o que você quer dizer. Como alternativa, considere escrever isso como um comentário.
precisa
3

Use os threads de entrada / saída assíncronos Boost, durma por x milissegundos;

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

boost::thread::sleep(boost::get_system_time() + boost::posix_time::millisec(1000));
Anum Sheraz
fonte
O que realmente acontecerá se você tentar dormir por 3 milissegundos? Serão 15-16 milissegundos? Você mediu isso?
Peter Mortensen
1

A pergunta é antiga, mas consegui descobrir uma maneira simples de fazer isso no meu aplicativo. Você pode criar uma macro C / C ++, como mostrado abaixo, para usá-la:

#ifndef MACROS_H
#define MACROS_H

#include <unistd.h>

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

#endif // MACROS_H
VPZ
fonte
1

Do C ++ 14 usando std e também seus literais numéricos:

#include <chrono>
#include <thread>

using namespace std::chrono;

std::this_thread::sleep_for(123ms);
Martin Flaska
fonte
0

Como um substituto do Win32 para sistemas POSIX:

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

while (1) {
    printf(".");
    Sleep((unsigned int)(1000.0f/20.0f)); // 20 fps
}
lama12345
fonte
Prefere nanosleep()a usleep(): este último é obsoleto e foi excluído do padrão POSIX mais recente.
precisa