C ++, usleep () is deprecated, workarounds for Windows / MingW?

I already found out with another question that Windows / MingW does not provide alternatives to nanosleep () and setitimer () for legacy usleep (). But my goal is to fix all warnings cppcheck gives, including usleep () style warnings.

So, is there any workaround to somehow avoid usleep () on Windows without using cygwin or installing many new dependencies / libraries? Thank.

+16
c ++ windows cppcheck usleep
Apr 27 '11 at 9:15
source share
6 answers

usleep() works with microseconds. In windows, to get a microsecond precesion, you should use the QueryPerformanceCounter () winapi function . Here you can learn how to use this pursuit.

-four
Apr 27 '11 at 9:26 a.m.
source share

I used this code from (from here ):

 #include <windows.h> void usleep(__int64 usec) { HANDLE timer; LARGE_INTEGER ft; ft.QuadPart = -(10*usec); // Convert to 100 nanosecond interval, negative value indicates relative time timer = CreateWaitableTimer(NULL, TRUE, NULL); SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0); WaitForSingleObject(timer, INFINITE); CloseHandle(timer); } 

Note that SetWaitableTimer() uses "100 nanosecond intervals ... Positive values ​​indicate absolute time ... Negative values ​​indicate relative time." and that "the actual accuracy of the timer depends on the capabilities of your equipment."

If you have a C ++ 11 compiler, you can use this portable version:

 #include <chrono> #include <thread> ... std::this_thread::sleep_for(std::chrono::microseconds(usec)); 

Kudos to Howard Hinnant, who developed the amazing <chrono> library (and whose answer is lower , deserves more love.)

If you don't have C ++ 11 but you have an incentive, you can instead this this :

 #include <boost/thread/thread.hpp> #include <boost/date_time/posix_time/posix_time.hpp> ... boost::this_thread::sleep(boost::posix_time::microseconds(usec)); 
+32
Jun 24 '13 at 19:30
source share

The multi-second mode of the Sleep() function is well described and well understood. It does nothing unpredictable. Sometimes a function is accused of unpredictability, i.e. When returning before the delay expires. I need to say that this is wrong. A thorough investigation will confirm that his behavior is absolutely predictable. The only problem is that there is a lot to read about it, and most of them are kidding. It is also often said that Windows is not an operating system. But such comments do not give anything, moreover, comments are used to hide the lack of knowledge. It annoys me that not even microsoft notices it and provides better documentation.

However, without exaggerating this small answer: the sleep () function is accurate when used properly and knowing its characteristics. Particular attention should be paid to sleep (0). This is a very powerful tool, especially when used in conjunction with the process priority class, thread priority, media timer settings and processor affinity mask.

Thus, as a rule, true sleep can be performed easily and safely until the period of interruption of the system. When it comes to sleep shorter than the interruption time, spinning is required. A higher resolution time source must be used in another to rotate for shorter periods of time. The most common source of this is a performance counter. QueryPerformanceCounter(*arg) provides incremental * arg. QueryPerformanceFrequency(*arg) provides the frequency at which the performance counter is incremented. Usually it is in MHz mode and depends on the base equipment. The frequency in the MHz range provides microsecond resolution. Thus, to achieve the desired time interval, you can use something with high resolution. However, the accuracy of this should be carefully considered: the OS returns the frequency of the performance counter as a constant. This is not true! Since the frequency is generated as a physical device, there is always a bias, and it is also not constant. It has thermal drift. More modern systems have less drift. But if the thermal drift is only 1 ppm, the error will be 1us / s. The offset can easily be a few 100. An offset of 100 in 1 MHz corresponds to 100US / s.

If a thread needs to wait any high-resolution time, it must establish a service flow. Both threads must have a named event. The service thread should sleep up to 1 interruption period before the desired sleep delay, and then rotate on the performance counter for the remaining microsecond. When a service flow reaches a finite time, it sets up a named event and ends. The calling thread will wake up because it was expecting the named event using the wait function.

Summary:

  • Sleep is well understood, but poorly documented.
  • Service flow can simulate hibernation with high resolution.
  • Such a service thread coulb will be used as a system service.
  • The accuracy of the performance counter should be carefully considered. Calibration required.

More information can be found in the Timestamp Windows project.

+8
Jul 13 '12 at 12:33
source share

New answer to old question:

Justification for the new answer: the tools / OS have been updated so that now there is a better choice than when the question was asked.

The std headers of C ++ 11 <chrono> and <thread> files have been in the VS toolkit for several years now. Using these headers, it is best encoded in C ++ 11 as:

 std::this_thread::sleep_for(std::chrono::microseconds(123)); 

I use microseconds only as an example of duration. You can use any duration when convenient:

 std::this_thread::sleep_for(std::chrono::minutes(2)); 

With C ++ 14 and some using directives, this can be written a little more compactly:

 using namespace std::literals; std::this_thread::sleep_for(2min); 

or

 std::this_thread::sleep_for(123us); 

This definitely works on VS-2013 (modulo chron literals). I am not sure about earlier versions of VS.

+6
Aug 31 '15 at 20:09
source share

I found this blog post about this . It uses a QueryPerformanceCounter . The laid out function:

 #include <windows.h> void uSleep(int waitTime) { __int64 time1 = 0, time2 = 0, freq = 0; QueryPerformanceCounter((LARGE_INTEGER *) &time1); QueryPerformanceFrequency((LARGE_INTEGER *)&freq); do { QueryPerformanceCounter((LARGE_INTEGER *) &time2); } while((time2-time1) < waitTime); } 

Hope this helps a bit.

+4
Apr 27 '11 at 9:20
source share

It depends on what granularity you need. If you say milliseconds, the Win32 Sleep function will do the job - see http://msdn.microsoft.com/en-us/library/ms686298%28v=vs.85%29.aspx . If you are talking about microseconds, then there is no easy way to do this, and you would be lucky to get such a timer resolution on Windows (which is not RTOS) or Linux would come to that.

+4
Apr 27 '11 at 9:26 a.m.
source share



All Articles