Зачем использовать select () вместо sleep ()? - PullRequest
15 голосов
/ 27 июня 2010

Я работаю над главой об аудио iPhone и наткнулся на фрагмент кода, который мне не понятен:

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

( Полный пример кода на страницах 163-166 ).Исходя из того, что я понимаю в коде, аудио обрабатывается в другом потоке, и цикл while предназначен только для предотвращения завершения основного потока во время обработки аудио.

Что я не понимаю, так это почемуselect() используется вместо sleep().

Из того, что я прочитал, select() используется для отслеживания изменений в вводе-выводе, и передача NULL не делает ничего значимого.Я запустил код, используя sleep(), и он работает, как ожидалось.(Мои знания о POSIX низкого уровня практически не существуют.)

Ответы [ 5 ]

19 голосов
/ 27 июня 2010

Выберите для точного ожидания менее секунды, и он более переносим, ​​чем спит.Есть и другие способы ожидания, см. этот вопрос .

Но параметр timeout для выбора должен быть не плавающим, а указателем на структуру timeval.Я удивлен кодом, который вы показываете, даже компилирует.Далее: за этим странным условным выбором следует безусловный сон (1).Выглядит для меня бессмысленно.

11 голосов
/ 27 июня 2010

Использование select() с NULL rfds, wfds и efds - идиоматический способ переноса сна с разрешением менее секунды.

5 голосов
/ 27 сентября 2011

Ну, сон (3) может быть реализован с помощью сигналов.Это зависит от платформы.

Когда вы используете select (2) и poll (2), вы знаете, что сигналы не будут задействованы, что часто очень полезно.Например, если вы используете alarm (2), вам также не следует использовать sleep (3), потому что «смешивать вызовы в alarm и sleep - плохая идея» (согласно man-странице.)

Кроме того, выбор и опрос дают вам гранулярность в миллисекундах во время сна, но сон имеет гранулярность только в секундах.

3 голосов
/ 06 июня 2012

Когда вы используете сигнал 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
0 голосов
/ 27 июня 2010

Нет причин делать это.Также нет причин спать ().Всегда следует ожидать хотя бы одного события - запроса на завершение работы программы.

...