Время ожидания select() сразу после долгого времени выполнения (C++)

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

Я полагаю, что ошибка, связанная с изменением стандартного входа во времени, - это то, что блокирует select.

Оглядываясь на Stackru, большинство проблем людей с select (), по-видимому, решаются путем сброса каждого макроса (FD_ZERO & FD_SET) каждый раз и использования правильного начального параметра для выбора. Я не думаю, что это проблемы здесь.

int            rc     = 0;
fd_set         fdset;
struct timeval timeout;

// -- clear out the response -- //
readValue = "";

// -- set the timeout -- //
timeout.tv_sec = passedInTimeout;  // 5 seconds
timeout.tv_usec = 0;

// -- indicate which file descriptors to select from -- //
FD_ZERO(&fdset);
FD_SET(passedInFileDescriptor, &fdset); //passedInFileDescriptor = 0

// -- perform the selection operation, with timeout -- //
rc = select(1, &fdset, NULL, NULL, &timeout);


if (rc == -1)  // -- select failed -- //
{
    result = TR_ERROR;
}
else if (rc == 0)  // -- select timed out -- //
{
    result = TR_TIMEDOUT;
}
else 
{
    if (FD_ISSET(mFileDescriptor, &fdset))
    {
        if(rc = readData(readValue) <= 0)
        {
            result = TR_ERROR;
        }
    } else {
       result = TR_SUCCESS;
    }
}

4 ответа

В некоторых ОС timeout модифицируется при звонке select отражать количество времени не спал. Не похоже, что вы используете повторно timeout в вашем примере, но убедитесь, что вы действительно переинициализируете его на 5 секунд каждый раз перед вызовом select,

Помните, что некоторые реализации "select" применяют строго спецификацию: "nfds - дескриптор файла с наибольшим номером в любом из трех наборов плюс 1". Итак, вам лучше изменить "1" на "selectedInFileDescriptor+1" в качестве первого параметра. Я не знаю, может ли это решить вашу проблему, но, по крайней мере, ваш код становится более... хм... "традиционным";)

до свидания

У меня та же проблема, она отлично работает на Windows, но не на Linux, и у меня maxfd установлен на последний сокет + 1. Это происходит периодически после длительных запусков. Я поднимаю соединение при принятии, а затем первый звонок периодически выбирает время ожидания.

Посмотрите на этот код:

if (FD_ISSET(mFileDescriptor, &fdset))
{
    if(rc = readData(readValue) <= 0)
    {
        result = TR_ERROR;
    }
} else { 
   result = TR_SUCCESS;
}

Здесь меня беспокоят две вещи:

  1. если в вашем FD нет данных (например, произошла ошибка), FD_ISSET() вернется false и ваша функция возвращаетсяTR_SUCCESS!?
  2. вы FD_SET(passedInFileDescriptor, &fdset), но проверьте другое значение: FD_ISSET(mFileDescriptor, &fdset), Если в какой-то момент mFileDescriptor!= PassInFileDescriptor, вы попадете в мое первое предположение.

Это должно выглядеть так:

if (FD_ISSET(passedInFileDescriptor, &fdset))
{
    if(rc = readData(readValue) <= 0)
    {
        result = TR_ERROR;
    }
    else 
    {
        result = TR_SUCCESS;
    }
}
else
{
    result = TR_ERROR;
}

Нет?

(Изменить: также этот ответ также указывает на проблему вашего использования select() с плохим значением high_fd)

Другое редактирование: ну, похоже, что парни никогда не возвращались... расстраивает.

Другие вопросы по тегам