Кроссплатформенная функция Sleep для C++

Возможно ли с помощью макросов сделать кроссплатформенный код Sleep? Например

#ifdef LINUX
#include <header_for_linux_sleep_function.h>
#endif
#ifdef WINDOWS
#include <header_for_windows_sleep_function.h>
#endif
...
Sleep(miliseconds);
...

7 ответов

Решение

Да, есть. То, что вы делаете, это оборачиваете различные системные спящие вызовы в вашу собственную функцию, а также включаете операторы, как показано ниже:

#ifdef LINUX
#include <unistd.h>
#endif
#ifdef WINDOWS
#include <windows.h>
#endif

void mySleep(int sleepMs)
{
#ifdef LINUX
    usleep(sleepMs * 1000);   // usleep takes sleep time in us (1 millionth of a second)
#endif
#ifdef WINDOWS
    Sleep(sleepMs);
#endif
}

Тогда ваш код звонит mySleep спать, а не делать прямые системные вызовы.

Ага. Но это работает только в C++11 и более поздних версиях.

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

где ms количество времени, которое вы хотите спать в миллисекундах.

Вы также можете заменить milliseconds с nanoseconds, microseconds, seconds, minutes, или же hours, (Это специализации типа std:: chrono:: duration.)

Обновление: в C++14, если вы спите в течение определенного времени, например, 100 миллисекунд, std::chrono::milliseconds(100) можно записать как 100ms, Это связано с пользовательскими литералами, которые были введены в C++11. В C++14 chrono библиотека была расширена для включения следующих пользовательских литералов:

  • std::literals::chrono_literals::operator""h
  • std::literals::chrono_literals::operator""min
  • std::literals::chrono_literals::operator""s
  • std::literals::chrono_literals::operator""ms
  • std::literals::chrono_literals::operator""us
  • std::literals::chrono_literals::operator""ns

Фактически это означает, что вы можете написать что-то вроде этого.

#include <chrono>
#include <thread>
using namespace std::literals::chrono_literals;

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

Обратите внимание, что в то время как using namespace std::literals::chrono_literals обеспечивает наименьшее количество загрязнения пространства имен, эти операторы также доступны при using namespace std::literals, или же using namespace std::chrono,

У shf301 была хорошая идея, но этот способ лучше:

#ifdef _WINDOWS
#include <windows.h>
#else
#include <unistd.h>
#define Sleep(x) usleep((x)*1000)
#endif

Тогда используйте как это:

Sleep(how_many_milliseconds);

Получите Boost.

#include <boost/thread/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
...
boost::this_thread::sleep(boost::posix_time::millisec(milliseconds));

Стандартным решением является вызов select() (требуется Winsock). Этот конкретный вызов имеет точно такое же поведение в Linux и Windows.

long value; /* time in microseconds */

struct timeval tv;
tv.tv_sec = value / 1000000;
tv.tv_usec = value % 1000000;
select(0, NULL, NULL, NULL, &tf);

Начиная с C++ 11 вы можете просто сделать это.

#include<chrono>
#include<thread>
int main(){
    std::this_thread::sleep_for(std::chrono::milliseconds(x));//sleeps for x milliseconds
    std::this_thread::sleep_for(std::chrono::seconds(x));//sleeps for x seconds  
    std::this_thread::sleep_for(std::chrono::minutes(x));//sleeps for x minutes
    std::this_thread::sleep_for(std::chrono::hours(x));//sleeps for x hours.
  return 0;  
}

Я не знаю, зачем вам использовать беспорядочные макросы, когда вы можете это сделать, этот метод отличный, кроссплатформенный и включен в стандарт C++.

В Linux помните, что у usleep есть предел. Вы не можете "спать" более 1000 секунд.

Я бы написал так

struct timespec req={0},rem={0};
req.tv_sec=(milisec/1000);
req.tv_nsec=(milisec - req.tv_sec*1000)*1000000;
nanosleep(&req,&rem);

Просто делать

#include <ctime>
int Sleep(int ms)
{
    clock_t starting = clock();
    while( clock() - starting < ms ) {}
    return 0;
}

Это проверяет текущее время (в миллисекундах), вычитает время начала из него, что дает количество времени, используемого функцией. Если это число меньше критического значения (целевое время), то оно ничего не делает, убивая небольшое количество времени. Это повторяется до тех пор, пока время не превысит критическое значение, а затем остановится.

РЕДАКТИРОВАТЬ: исправлены ошибки кода

Другие вопросы по тегам