为什么使用select()而不是sleep()?

时间:2010-06-26 22:06:35

标签: c multithreading posix

我正在编写一个关于iPhone音频的章节,并且遇到了一段我无法理解的代码:

while (aqc.playPtr < aqc.sampleLen) 
{
    select(NULL, NULL, NULL, NULL, 1.0);
}

Full code sample is on pages 163-166)。根据我对代码的理解,音频正在另一个线程上处理,而while循环就是为了防止主线程在音频处理过程中终止。

我不明白为什么使用select()代替sleep()

从我读过的select()用于监视I / O的变化并传递它NULL并没有做任何有意义的事情。我使用sleep()运行了代码,它按预期工作。 (我对低级POSIX的了解几乎不存在。)

6 个答案:

答案 0 :(得分:19)

选择允许准确的次秒等待,并且比睡眠更便携。还有其他等待方式,请参阅this question

但select的timeout参数不应该是float,而是指向struct timeval的指针。我对您展示的代码甚至编译感到惊讶。更多:这个奇怪的条件选择之后是无条件睡眠(1)。对我来说毫无意义。

答案 1 :(得分:11)

select()NULL rfds一起使用,wfdsefds是以次秒级分辨率进行便携式睡眠的惯用方式。

答案 2 :(得分:5)

嗯,睡眠(3)可以通过使用信号来实现。这取决于平台。

使用select(2)和poll(2)时,您知道不会涉及任何信号,这通常非常有用。例如,如果你正在使用alarm(2),你也不应该使用sleep(3),因为“混合调用警报和睡眠是一个坏主意”(根据手册页。)

此外,select和poll在睡眠时会给你毫秒级的粒度,但是睡眠只有几秒钟的粒度。

答案 3 :(得分:3)

当您在应用程序中使用SIGALM信号并使用(u)sleep函数时,当SIGALRM发生时,程序立即从睡眠函数返回,因此最好的睡眠方式是等待select函数。

struct timeval tv;

tv.tv_sec = 1;
tv.tv_usec = 1000;

do
{
  ret = select(1, NULL, NULL, NULL, &tv);
}
while((ret == -1)&&(errno == EINTR)); //select is interruped too

答案 4 :(得分:0)

使用“选择”而不是“睡眠”的真正原因是睡眠的准确性,尤其是音频或视频播放。在Linux或Windows或其他操作系统上使用'select'可以获得比'sleep'更高的精确时间间隔。

令我惊讶的是,许多人实际上不知道为什么。并且请不要再对程序员感到羞耻/编写这样的代码。

答案 5 :(得分:-3)

没有理由这样做。也没有理由睡觉()。应该总是期待至少一个事件 - 程序关闭请求。