I'm working through a chapter about iPhone audio and have come across a section of code that I can't make sense of:
while (aqc.playPtr < aqc.sampleLen)
{
select(NULL, NULL, NULL, NULL, 1.0);
}
(Full code sample is on pages 163-166). From what I understand of the code the audio is being processed on another thread and 开发者_StackOverflow中文版the while loop is just there to prevent the main thread from terminating while audio is still being processed.
What I don't understand is why select()
is being used instead of sleep()
.
From what I've read select()
is used to monitor changes in I/O and passing it NULLs doesn't do anything meaningful. I've ran the code using sleep()
and it works as expected. (My knowledge of low level POSIX is almost non-existant.)
Select allow for accurate sub second wait, and is more portable than sleep. There are other ways to wait, see this question.
But the timeout parameter of select should not be a float but a pointer to struct timeval. I'm surprised the code you show even compiles. More : this strange conditional select is followed by an unconditional sleep(1). Looks pointless to me.
Using select()
with NULL
rfds
, wfds
and efds
is an idiomatic way of portably sleeping with subsecond resolution.
Well, sleep(3) may be implemented by using signals. It depends on the platform.
When you use select(2) and poll(2), you know that no signals will be involved, which is often very useful. For example, if you are using alarm(2), you should not use sleep(3) as well, because "mixing calls to alarm and sleep is a bad idea" (according to the man page.)
Also, select and poll give you millisecond granularity when sleeping, but sleep only has a granularity in terms of seconds.
When you use SIGALM signal in your application and you use (u)sleep
functions, when SIGALRM occurs program immediately return from sleep function, so the best way to sleep is to wait on select
function.
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
The real reason to use 'select' instead of 'sleep' is the accuracy of sleep, especially the audio or video playback. Use 'select' can get higher precision time interval for sleeping on linux or windows or other OS than 'sleep'.
I am surprised that many people actually don't know why. And please stop to shame on the programmer / write of such a code.
There's no reason to do it. There's no reason ever to Sleep() either. One should always be expecting at least one event - program shutdown request.
精彩评论