Кроссплатформенная функция 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;
}
Это проверяет текущее время (в миллисекундах), вычитает время начала из него, что дает количество времени, используемого функцией. Если это число меньше критического значения (целевое время), то оно ничего не делает, убивая небольшое количество времени. Это повторяется до тех пор, пока время не превысит критическое значение, а затем остановится.
РЕДАКТИРОВАТЬ: исправлены ошибки кода