如何在纳秒或毫秒级别上阻塞线程(或进程)?
请注意,无法使用sleep函数,因为其参数单位始终为秒。
如何在纳秒或毫秒级别上阻塞线程(或进程)?
请注意,无法使用sleep函数,因为其参数单位始终为秒。
nanosleep
或clock_nanosleep
是您应该使用的函数(后者允许您指定绝对时间而不是相对时间,并使用单调时钟或其他时钟,而不仅仅是实时时钟,如果运营商重置它可能会倒退)。
然而,请注意,就分辨率而言,您很少能获得比几微秒更好的效果,而且它总是将休眠持续时间向上舍入,而不是向下舍入。 (无论如何,向下舍入通常都是不可能的,因为在大多数机器上,进入和退出内核空间需要超过一微秒的时间。)
此外,如果可能,建议使用阻塞等待事件而不是睡眠一小段时间然后进行轮询的调用。例如,pthread_cond_wait
、pthread_cond_timedwait
、sem_wait
、sem_timedwait
、select
、read
等,这取决于您的线程执行的任务以及它如何与其他线程同步和/或与外部世界通信。
clock_nanosleep
。使用相对时间,除非您采取额外的预防措施根据测量时间调整睡眠间隔,否则会累积误差。 - R.. GitHub STOP HELPING ICE一种相对便携的方法是使用select()
或pselect()
而不使用文件描述符:
void sleep(unsigned long nsec) {
struct timespec delay = { nsec / 1000000000, nsec % 1000000000 };
pselect(0, NULL, NULL, NULL, &delay, NULL);
}
pselect
的系统几乎肯定也具有 nanosleep
。它们都是由 POSIX 发明的,并且同时添加,我想是这样的。 - R.. GitHub STOP HELPING ICEstruct
,没有注意到它有 C 标签。 - Maxim Egorushkinppoll()
,它是在很久以前就有的 pselect()
(我想应该还有 nanosleep()
)。 - Alexis Wilkepthread_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。
sleep
及其变体是针对调用线程而不是进程的。然而,使用pthread_cond_wait
而不是睡眠函数的想法可能是一个非常好的想法,特别是如果微小的睡眠是为了轮询某些条件。 - R.. GitHub STOP HELPING ICE尝试使用usleep()。是的,这不会给你纳秒级精度,但微秒也可以工作 => 毫秒也可以。
2.0000045
,这将失败。 - RajSanpuiusleep
函数在POSIX 2003标准中被废弃,且在2008年被移除。 - R.. GitHub STOP HELPING ICEnanosleep
可以让你指定睡眠的精度,最小单位可以到纳秒级别。但是由于内核/CPU的限制,实际的睡眠分辨率可能会更大。
由于通常Linux发行版不是(硬)实时操作系统,因此在一般的Linux操作系统上实现精确的纳秒分辨率将是不可能的。如果您确实需要对时间进行精细控制,请考虑使用这样的操作系统。
维基百科在这里列出了一些实时操作系统:http://en.wikipedia.org/wiki/RTOS(请注意,它没有说明它们是软实时还是硬实时,因此您需要进行一些研究)。