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

zee*_*onk 13 c posix

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

cni*_*tar 12

该功能usleep已从SUSv4中删除.您应该使用nanosleep替代或计时器(setitimer等).

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

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

从而:

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


Jen*_*edt 11

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

不,POSIX规范usleep明确说明

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

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

正如其他人已经提到的,POSIX功能nanosleep现在正在替换usleep,您应该使用它.C(因为C11)具有thrd_sleep模拟的功能nanosleep.


Bil*_*nch 6

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

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


Bri*_*and 6

请注意,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 */
}
Run Code Online (Sandbox Code Playgroud)

如果您需要将线程唤醒除了定期超时之外的其他内容,请查看条件变量和pthread_cond_timedwait().