ElSajko
ElSajko

Reputation: 1640

Cross platform Sleep function for C++

Is it possible with macros make cross platform Sleep code? For example

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

Upvotes: 48

Views: 52373

Answers (7)

RSG
RSG

Reputation: 11

since c++ 11 you could just do this.

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

I don't know why would you want to use messy macros when you can do this, this method is great, cross platform and is included in the c++ standard.

Upvotes: 1

Michael Francis
Michael Francis

Reputation: 8747

Yup. But this only works in C++11 and later.

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

where ms is the amount of time you want to sleep in milliseconds.

You can also replace milliseconds with nanoseconds, microseconds, seconds, minutes, or hours. (These are specializations of the type std::chrono::duration.)

Update: In C++14, if you're sleeping for a set amount of time, for instance 100 milliseconds, std::chrono::milliseconds(100) can be written as 100ms. This is due to user defined literals, which were introduced in C++11. In C++14 the chrono library has been extended to include the following user defined literals:

Effectively this means that you can write something like this.

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

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

Note that, while using namespace std::literals::chrono_literals provides the least amount of namespace pollution, these operators are also available when using namespace std::literals, or using namespace std::chrono.

Upvotes: 84

shf301
shf301

Reputation: 31394

Yes there is. What you do is wrap the different system sleeps calls in your own function as well as the include statements like below:

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

Then your code calls mySleep to sleep rather than making direct system calls.

Upvotes: 48

Dženan
Dženan

Reputation: 3395

shf301 had a good idea, but this way is better:

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

Then use like this:

Sleep(how_many_milliseconds);

Upvotes: 30

The Simba
The Simba

Reputation: 11

In linux remember that usleep has a limit. You can't 'sleep' more than 1000 seconds.

I would write like this

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

Upvotes: 1

Joshua
Joshua

Reputation: 43217

The stock solution is the select() call (requires Winsock). This particular call has exactly the same behavior on Linux and 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);

Upvotes: 8

Mike C
Mike C

Reputation: 1238

Get Boost.

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

Upvotes: 19

Related Questions