RajSanpui
RajSanpui

Reputation: 12054

How to make a thread sleep/block for nanoseconds (or at least milliseconds)?

How can I block my thread (maybe process) for nanoseconds or maybe for a milliseconds (at least) period?

Please note that I can't use sleep, because the argument to sleep is always in seconds.

Upvotes: 12

Views: 39718

Answers (7)

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136208

One relatively portable way is to use select() or pselect() with no file descriptors:

void sleep(unsigned long nsec) {
    struct timespec delay = { nsec / 1000000000, nsec % 1000000000 };
    pselect(0, NULL, NULL, NULL, &delay, NULL);
}

Upvotes: 9

user563205
user563205

Reputation:

On an embedded system with access to multiple hardware timers, create a high-speed clock for your nanosecond or microsecond waits. Create a macro to enable and disable it, and handle your high-resolution processing in the timer interrupt service routine.

If wasting power and busywaiting is not an issue, perform some no-op instructions - but verify that the compiler does not optimize your no-ups out. Try using volatile types.

Upvotes: 1

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215193

nanosleep or clock_nanosleep is the function you should be using (the latter allows you to specify absolute time rather than relative time, and use the monotonic clock or other clocks rather than just the realtime clock, which might run backwards if an operator resets it).

Be aware however that you'll rarely get better than several microseconds in terms of the resolution, and it always rounds up the duration of sleep, rather than rounding down. (Rounding down would generally be impossible anyway since, on most machines, entering and exiting kernelspace takes more than a microsecond.)

Also, if possible I would suggest using a call that blocks waiting for an event rather than sleeping for tiny intervals then polling. For instance, pthread_cond_wait, pthread_cond_timedwait, sem_wait, sem_timedwait, select, read, etc. depending on what task your thread is performing and how it synchronizes with other threads and/or communicates with the outside world.

Upvotes: 14

Douglas Leeder
Douglas Leeder

Reputation: 53310

nanosleep allows you to specify the accuracy of the sleep down to nano-seconds. However the actual resolution of your sleep is likely to be much larger due to the kernel/CPU limitations.

Upvotes: 3

Furquan
Furquan

Reputation: 678

Using any variant of sleep for pthreads, the behaviour is not guaranteed. All the threads can also sleep since the kernel is not aware of the different threads. Hence a solution is required which the pthread library can handle rather than the kernel.

A safer and cleaner solution to use is the pthread_cond_timedwait...

pthread_mutex_t fakeMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t fakeCond = PTHREAD_COND_INITIALIZER;

void mywait(int timeInSec)
{
struct timespec timeToWait;
struct timeval now;
int rt;

gettimeofday(&now,NULL);

timeToWait.tv_sec = now.tv_sec + timeInSec;
timeToWait.tv_nsec = now.tv_usec*1000;

pthread_mutex_lock(&fakeMutex);
rt = pthread_cond_timedwait(&fakeCond, &fakeMutex, &timeToWait);
pthread_mutex_unlock(&fakeMutex);
printf("\nDone\n");
}

void* fun(void* arg)
{
printf("\nIn thread\n");
mywait(5);
}

int main()
{
pthread_t thread;
void *ret;

pthread_create(&thread, NULL, fun, NULL);
pthread_join(thread,&ret);
}

For pthread_cond_timedwait , you need to specify how much time to wait from current time.

Now by the use of the function mywait() only the thread calling it will sleep and not the other pthreads.

Upvotes: 3

AVH
AVH

Reputation: 11506

Accurate nano-second resolution is going to be impossible on a general Linux OS, due to the fact that generally Linux distributions aren't (hard) real-time OSes. If you really need that fined grained control over timing, consider using such an operating system.

Wikipedia has a list of some real-time operating systems here: http://en.wikipedia.org/wiki/RTOS (note that it doesn't say if they are soft or hard real time, so you'll have to do some research).

Upvotes: 2

Mihran Hovsepyan
Mihran Hovsepyan

Reputation: 11088

Try usleep(). Yes this wouldn't give you nanosecond precision but microseconds will work => miliseconds too.

Upvotes: 3

Related Questions