43

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);
...
MiJyn
  • 4,117
  • 4
  • 34
  • 58
ElSajko
  • 1,357
  • 3
  • 14
  • 30
  • If you don't mind the processor whirring away and have C++11, you can use ``. – chris Jun 06 '12 at 16:24
  • 14
    Why would you have the processor whirring away? If you have C++11 you can use something like `std::this_thread::sleep_for(std::chrono::milliseconds(n))` which should not consume any CPU. – R. Martinho Fernandes Jun 06 '12 at 16:27
  • 5
    @KamilKrzyszczuk that's an almost worthless description. I doubt there is much "pure C++" code out there, since no compiler in existence can handle "pure C++". For what is worth, C++11 *is not an extension*, it's actually the real "pure C++". – R. Martinho Fernandes Jun 06 '12 at 16:37
  • @R.MartinhoFernandes, I never realized that existed; I just started with `chrono` yesterday. That saves me a lot of trouble, thanks. – chris Jun 06 '12 at 16:41
  • In my programs, I use ``. It's very reliable. – Rontogiannis Aristofanis Jun 06 '12 at 16:56

7 Answers7

72

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.

Community
  • 1
  • 1
Michael Dorst
  • 6,449
  • 10
  • 35
  • 64
44

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.

shf301
  • 30,022
  • 2
  • 46
  • 83
  • 7
    #ifdef LINUX int Sleep(int sleepMs) { return usleep(sleepMs * 1000); } #endif – Joshua Jun 06 '12 at 16:43
  • ya, that would be great, but usleep doesnt stop consuming CPU. For example: while(1) { usleep(1000*1000);/*1sec?*/ cout << 1; } Then after this one sec, output is many of "1" characters. – ElSajko Jun 06 '12 at 16:46
  • @KamilKrzyszczuk: No, `usleep` does _not_ consume CPU, it stops the process entirely for a while. – Mooing Duck Jun 06 '12 at 16:49
  • so why output for code above is many of 1 characters instead of just one? I understand that is not related. But how to fix it? – ElSajko Jun 06 '12 at 16:51
  • 1
    @KamilKrzyszczuk: because you made some other mistake. The code you posted should print one `1` character per second. – Mooing Duck Jun 06 '12 at 16:52
  • There is no mistake in while(true) codeblock, as u can see there is just sleep and cout, and this code I compiled. Btw. I used usleep(1000) and it work for 1 sec. :) – ElSajko Jun 06 '12 at 16:58
  • 2
    Why take an `int` for `mySleep`? Wouldn't an `unsigned int` be a better choice? After all, it's not like you can sleep for negative seconds! :P – Sebastian Lenartowicz Aug 28 '16 at 15:33
  • If anyone tries this with MinGW derivative (ie gcc g++) on Windows, there is a problem with the macros. If you add `-DWINDOWS` to your compilation parameters (like `g++ xx.cpp -DWINDOWS`), the CPU consumption is over. – SeanTolstoyevski Dec 23 '20 at 23:51
28

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);
Dženan
  • 2,687
  • 2
  • 29
  • 36
18

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));
Mike C
  • 1,113
  • 9
  • 23
8

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);
Joshua
  • 34,237
  • 6
  • 59
  • 120
1

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);
The Simba
  • 11
  • 1
0

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.

MR MEME
  • 1
  • 3