49

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); ... 
5
  • If you don't mind the processor whirring away and have C++11, you can use <chrono>. Commented Jun 6, 2012 at 16:24
  • 15
    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. Commented Jun 6, 2012 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++". Commented Jun 6, 2012 at 16:37
  • @R.MartinhoFernandes, I never realized that existed; I just started with chrono yesterday. That saves me a lot of trouble, thanks. Commented Jun 6, 2012 at 16:41
  • In my programs, I use <time.h>. It's very reliable. Commented Jun 6, 2012 at 16:56

7 Answers 7

85

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.

Sign up to request clarification or add additional context in comments.

1 Comment

@ThePirate42 haha thanks. At the time it was posted though, most people were not yet using C++11, so the accepted answer was more generally useful.
49

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.

10 Comments

#ifdef LINUX int Sleep(int sleepMs) { return usleep(sleepMs * 1000); } #endif
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.
@KamilKrzyszczuk: No, usleep does not consume CPU, it stops the process entirely for a while.
@KamilKrzyszczuk: because you made some other mistake. The code you posted should print one 1 character per second.
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
|
30

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); 

Comments

19

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)); 

1 Comment

this is now in C++11. posix_time is called chrono though.
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); 

2 Comments

interesting solution, but I liked your comment on shf301's answer better.
this doesn't work on Windows, it returns immediately, regardless of the requested timeout
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); 

Comments

1

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.