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

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

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

Оглядываясь на StackOverflow, большинство проблем людей с 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 ]

1 голос
/ 02 апреля 2011

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

1 голос
/ 11 мая 2011

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

1 голос
/ 02 апреля 2011

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

Пока

0 голосов
/ 17 августа 2011

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

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 )

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

...