如何使线程休眠/阻塞纳秒(或至少毫秒)?

时间:2011-04-27 11:58:14

标签: c linux pthreads sleep

如何阻止我的线程(可能是进程)纳秒或者可能是毫秒(至少)一段时间?

请注意我不能使用睡眠,因为睡眠的参数总是在几秒钟内。

7 个答案:

答案 0 :(得分:10)

nanosleepclock_nanosleep是您应该使用的功能(后者允许您指定绝对时间而不是相对时间,并使用单调时钟或其他时钟而不仅仅是实时时钟,如果操作员重置它可能会向后运行。)

请注意,在分辨率方面,你很少会比几微秒好,并且它总是会使睡眠时间变长,而不是向下舍入。 (无论如何,向下舍入通常是不可能的,因为在大多数机器上,进入和退出内核空间需要超过一微秒。)

另外,如果可能的话,我建议使用一个阻止等待事件的呼叫,而不是在一小段时间内休眠然后进行轮询。例如,pthread_cond_waitpthread_cond_timedwaitsem_waitsem_timedwaitselectread等等,具体取决于您的主题执行的任务和它如何与其他线程同步和/或与外界通信。

答案 1 :(得分:5)

一种相对可移植的方法是使用select()pselect()而没有文件描述符:

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

答案 2 :(得分:3)

试试usleep()。是的,这不会给你纳秒精度,但微秒将工作=>也是毫秒。

答案 3 :(得分:3)

对pthreads使用任何睡眠变体,不保证行为。由于内核不知道不同的线程,所有线程也可以休眠。因此,需要一个解决方案,pthread库可以处理而不是内核。

使用更安全,更清洁的解决方案是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);
}

对于pthread_cond_timedwait,您需要指定从当前时间等待的时间。

现在通过使用mywait()函数,只有调用它的线程才会睡眠而不是其他pthreads。

答案 4 :(得分:3)

nanosleep允许您将睡眠精度指定为纳秒。但是,由于内核/ CPU限制,睡眠的实际分辨率可能会大得多。

答案 5 :(得分:2)

在一般的Linux操作系统上,准确的纳秒级分辨率是不可能的,因为通常Linux发行版不是(硬)实时操作系统。如果确实需要对时序进行精细控制,请考虑使用这样的操作系统。

维基百科在这里列出了一些实时操作系统:http://en.wikipedia.org/wiki/RTOS(请注意,它没有说明它们是软实时还是硬实时,所以你必须做一些研究。) / p>

答案 6 :(得分:1)

在可访问多个硬件定时器的嵌入式系统上,为您的纳秒或微秒等待创建高速时钟。创建一个宏来启用和禁用它,并在定时器中断服务程序中处理高分辨率处理。

如果浪费电源并且忙碌等待不是问题,请执行一些无操作指令 - 但验证编译器不会优化您的禁止输出。尝试使用volatile类型。