Время ожидания 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;
}
Здесь меня беспокоят две вещи:
- если в вашем FD нет данных (например, произошла ошибка),
FD_ISSET() вернется
false
и ваша функция возвращаетсяTR_SUCCESS
!? - вы
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)
Другое редактирование: ну, похоже, что парни никогда не возвращались... расстраивает.