How to make thread sleep less than a millisecond on Windows


Question

On Windows I have a problem I never encountered on Unix. That is how to get a thread to sleep for less than one millisecond. On Unix you typically have a number of choices (sleep, usleep and nanosleep) to fit your needs. On Windows, however, there is only Sleep with millisecond granularity.

On Unix, I can use the use the select system call to create a microsecond sleep which is pretty straightforward:

int usleep(long usec)
{
    struct timeval tv;
    tv.tv_sec = usec/1000000L;
    tv.tv_usec = usec%1000000L;
    return select(0, 0, 0, 0, &tv);
}

How can I achieve the same on Windows?

1
51
2/15/2015 9:59:50 PM

Accepted Answer

On Windows the use of select forces you to include the Winsock library which has to be initialized like this in your application:

WORD wVersionRequested = MAKEWORD(1,0);
WSADATA wsaData;
WSAStartup(wVersionRequested, &wsaData);

And then the select won't allow you to be called without any socket so you have to do a little more to create a microsleep method:

int usleep(long usec)
{
    struct timeval tv;
    fd_set dummy;
    SOCKET s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    FD_ZERO(&dummy);
    FD_SET(s, &dummy);
    tv.tv_sec = usec/1000000L;
    tv.tv_usec = usec%1000000L;
    return select(0, 0, 0, &dummy, &tv);
}

All these created usleep methods return zero when successful and non-zero for errors.

-2
2/15/2015 9:56:09 PM

This indicates a mis-understanding of sleep functions. The parameter you pass is a minimum time for sleeping. There's no guarantee that the thread will wake up after exactly the time specified. In fact, threads don't 'wake up' at all, but are rather chosen for execution by the scheduler. The scheduler might choose to wait much longer than the requested sleep duration to activate a thread, especially if another thread is still active at that moment.


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon