How to Make Thread Sleep Less Than a Millisecond on Windows

Thread.Sleep for less than 1 millisecond

You can't do this. A single sleep call will typically block for far longer than a millisecond (it's OS and system dependent, but in my experience, Thread.Sleep(1) tends to block for somewhere between 12-15ms).

Windows, in general, is not designed as a real-time operating system. This type of control is typically impossible to achieve on normal (desktop/server) versions of Windows.

The closest you can get is typically to spin and eat CPU cycles until you've achieved the wait time you want (measured with a high performance counter). This, however, is pretty awful - you'll eat up an entire CPU, and even then, you'll likely get preempted by the OS at times and effectively "sleep" for longer than 1ms...

Pause a thread for less than one millisecond

Send 20 messages and then sleep for 1 millisecond?

You can't sleep for less than the scheduler quantum, unless you have a hardware interrupt other than the system timer. Read the answers in the question you linked, they explain why the suggested approach doesn't actually work.

Even with this approach you might sleep longer than 1ms, or since the messages aren't sent instantaneously, the whole operation will surely take longer than 1ms, reducing the overall rate.

So, inspect a precision clock source every time you wake, and calculate how many messages to send based on elapsed time, don't use a constant 20.

Sleeping for less than a millisecond in C++

No. Under Windows, even without sleeping you can't ensure that two consecutive instructions will be carried out with less than a millisecond between them.

Precise thread sleep needed. Max 1ms error

From the question tags I suppose you are on windows.
Take a look at Multimedia Timers, they advertise precision under 1ms.
Another options is to use Spin Locks but this will basically keep a cpu core at maximum usage.

Sleep for milliseconds

Note that there is no standard C API for milliseconds, so (on Unix) you will have to settle for usleep, which accepts microseconds:

#include <unistd.h>

unsigned int microseconds;
...
usleep(microseconds);

Timer: period less than a millisecond

If you want to sleep, Thread.sleep has 2 methods, one of which accepts nanoseconds. If you want to schedule a task, you can use a ScheduledExecutorService which schedule methods can use nanoseconds too.

As explained by @MarkoTopolnik, the result will most likely not be precise to the nanosecond.

Thread.Sleep(1) takes longer than 1ms

Timers other than Stopwatch are incremented by the clock interrupt. Which by default ticks 64 times per second on Windows. Or 15.625 milliseconds. So a Thread.Sleep() argument less than 16 doesn't give you the delay you are looking for, you'll always get at least that 15.625 interval. Similarly, if you read, say, Environment.TickCount or DateTime.Now and wait less than 16 millisecond then you'll read the same value back and think 0 msec has passed.

Always use Stopwatch for small increment measurements, it uses a different frequency source. Its resolution is variable, it depends on the chipset on the motherboard. But you can rely on it being better than a microsecond. Stopwatch.Frequency gives you the rate.

The clock interrupt rate can be changed, you have to pinvoke timeBeginPeriod(). That can get you down to a single millisecond and actually make Thread.Sleep(1) accurate. Best not to do this, it is very power unfriendly.



Related Topics



Leave a reply



Submit