usleep()在C中实现为忙等待吗?

我正在使用pthreads构建一个multithreading应用程序,需要一个线程来定期检查一些东西。 在此线程之间的时间内不应使用任何CPU。 usleep()吗? usleep()不忙等待吗? 或者有更好的解决方案吗?

函数usleep已从SUSv4中删除。 您应该使用nanosleep或定时器( setitimer等)。

正如R ..在评论中注意到,睡眠是否应该作为忙碌的等待来实现:

  • 该线程将继续使用CPU
  • 其他(低优先级)线程无法运行

从而:

  • 有些人可能会使用信号(我认为SUSv3提到了SIGALARM?)
  • 有些人可能会使用花哨的计时器

usleep不是C标准的一部分,而是古老的POSIX标准,但见下文)

不,我们的POSIX规范明确指出

usleep()函数将导致调用线程被暂停执行…

所以这显然要求它暂停执行并将资源提供给其他进程或线程。

正如其他人已经提到的,POSIXfunctionnanosleep现在正在取代我们,你应该使用它。 正在开发的新C标准具有在thrd_sleep之后建模的函数nanosleep

请注意,usleep()和nanosleep()都可以被信号中断。 nanosleep()允许您传入额外的timespec指针,如果发生这种情况,将存储剩余时间。 因此,如果你真的需要保证你的延迟时间,你可能想要围绕nanosleep()编写一个简单的包装器。

请注意,这不是经过测试,而是沿着这些方向进行测试:

 int myNanoSleep(time_t sec, long nanosec) { /* Setup timespec */ struct timespec req; req.tv_sec = sec; req.tv_nsec = nanosec; /* Loop until we've slept long enough */ do { /* Store remainder back on top of the original required time */ if( 0 != nanosleep( &req, &req ) ) { /* If any error other than a signal interrupt occurs, return an error */ if(errno != EINTR) return -1; } else { /* nanosleep succeeded, so exit the loop */ break; } } while( req.tv_sec > 0 || req.tv_nsec > 0 ) return 0; /* Return success */ } 

如果您需要唤醒线程以外的其他事情,请查看条件变量和pthread_cond_timedwait()

在Linux上,它是通过nanosleep系统调用实现的,这不是繁忙的等待。

使用strace,我可以看到对usleep(1)的调用被转换为nanosleep({0, 1000}, NULL)

usleep()是一个基于系统计时器的C运行时库函数。
nanosleep()是一个系统调用。

只有MS-DOS和类似的同时,才能将hibernatefunction实现为忙等待。 任何提供多任务处理的实际操作系统都可以轻松地提供睡眠function,作为协调任务和进程的机制的简单扩展。

值得一提的是,WINE [lazily?]实现usleep作为对select()的调用:

 #ifndef HAVE_USLEEP int usleep (unsigned int useconds) { #if defined(__EMX__) DosSleep(useconds); return 0; #elif defined(__BEOS__) return snooze(useconds); #elif defined(HAVE_SELECT) struct timeval delay; delay.tv_sec = useconds / 1000000; delay.tv_usec = useconds % 1000000; select( 0, 0, 0, 0, &delay ); return 0; #else /* defined(__EMX__) || defined(__BEOS__) || defined(HAVE_SELECT) */ errno = ENOSYS; return -1; #endif /* defined(__EMX__) || defined(__BEOS__) || defined(HAVE_SELECT) */ } #endif /* HAVE_USLEEP */ 

值得一提的是,nanosleep(在GLIBC中)似乎只是一个空函数调用(其他任何东西,延迟可能会转移到微秒范围内)。

 /* Pause execution for a number of nanoseconds. */ int __libc_nanosleep (const struct timespec *requested_time, struct timespec *remaining) { __set_errno (ENOSYS); return -1; }