C 中的 usleep() 是不是实现为忙等待?

Posted

技术标签:

【中文标题】C 中的 usleep() 是不是实现为忙等待?【英文标题】:Is usleep() in C implemented as busy wait?C 中的 usleep() 是否实现为忙等待? 【发布时间】:2011-12-30 16:38:03 【问题描述】:

我正在使用pthreads 构建一个多线程应用程序,并且需要一个线程来定期检查一些东西。在此线程之间的时间不应使用任何 CPU。 usleep() 可以做到这一点吗? usleep() 不忙吗?还是有更好的解决方案?

【问题讨论】:

我认为 pthreads 有一个可能有用的yield() 功能。 usleep与C语言无关,它是操作系统的特性。 @KerrekSB:pthread_yield 不会降低 CPU 使用率,只会导致线程相对于具有相同优先级的其他线程暂时降低优先级。 【参考方案1】:

函数 usleep 已从 SUSv4 中删除。您可能应该改用nanosleep 或计时器(setitimer 等)。

正如 R.. 在 cmets 中所指出的,睡眠是否应该实现为忙等待:

线程将继续使用 CPU 其他(低优先级)线程将没有机会运行

因此:

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

【讨论】:

usleep 不是 C 库的一部分,AFAIK。 @JensGustedt 这不是标准的。但是libc(glibc、bsd libc 等)通常有它。所以,如果有人拥有它,那就是 C 库。 标准但 POSIX :) @JensGustedt kernel.org 提到它不在 SUSv4 中。在 SUSv4 中搜索它一无所获。 它不能实现为忙等待,因为这会阻止其他低优先级线程/进程运行。【参考方案2】:

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

不,usleep 的 POSIX 规范明确指出

usleep() 函数会导致调用线程被挂起 从执行...

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

正如其他人已经提到的,POSIX 函数nanosleep 现在正在替换usleep,您应该使用它。 C(因为C11)有一个函数thrd_sleep,它模仿nanosleep

【讨论】:

【参考方案3】:

请注意,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()

【讨论】:

这一直很有趣,因为在 POSIX 睡眠函数中,请求的时间不仅不是上限(因为,与其他操作系统一样,系统可以根据需要随时重新安排线程),但由于信号,甚至不是下限。本质上,类似睡眠的函数可以在他们最喜欢的时候返回。 :-D【参考方案4】:

在 Linux 上,它是通过 nanosleep system call 实现的,这不是忙等待。

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

【讨论】:

【参考方案5】:

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

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

【讨论】:

以上是关于C 中的 usleep() 是不是实现为忙等待?的主要内容,如果未能解决你的问题,请参考以下文章

如何让C语言sleep()函数等待时间小于1秒

在 PHP 中 sleep 和 usleep 的行为是不是不同?

菜鸟询问,shell 不想使用sleep控制时间

linux c的四种定时方式(sleep/usleep/select/ioctl)

php--------暂停函数 sleep() 与 usleep() 的区别

PHP 暂停函数 sleep() 与 usleep() 的区别