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() 是不是实现为忙等待?的主要内容,如果未能解决你的问题,请参考以下文章
在 PHP 中 sleep 和 usleep 的行为是不是不同?
linux c的四种定时方式(sleep/usleep/select/ioctl)