Most of the time this code works just fine. But sometimes when the executable has been running for a while, select() appears to time out immediately, then get into a weird state where it keeps getting called, timing out immediately, over and over. Then it has to be killed from the outside.
My guess would be that the way that standard input changes overtime is at fault - that is what select is blocking on.
Looking around on StackOverflow, most of people's select() troubles seem to be solved by making sure to reset with the macros (FD_ZERO & FD_SET) every time and using the right initial parameter to select. I don't think those are the issues here.
int rc = 0;
fd_set 开发者_如何学Python 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;
}
}
Beware that some implementaions of "select" apply strictly the specification: "nfds is the highest-numbered file descriptor in any of the three sets, plus 1". So, you'd better to change "1" with "passedInFileDescriptor+1" as first parameter. I don't know if this can solve your problem, but at least your code becomes more... uhm... "traditional" ;)
Bye
On some OSes, timeout
is modified when calling select
to reflect the amount of time not slept. It doesn't look like you're reusing timeout
in your example, but make sure that you are indeed reinitializing it to 5 seconds every time before calling select
.
I'm having the same problem, it works fine on windows but not on linux and I have the maxfd set to last socket + 1. It occurs periodically after long runs. I pick up the connection on accept and then the first call to select periodically times out.
Look at this code:
if (FD_ISSET(mFileDescriptor, &fdset))
{
if(rc = readData(readValue) <= 0)
{
result = TR_ERROR;
}
} else {
result = TR_SUCCESS;
}
There are two things bothering me here:
- if your FD has no data in it (like, say, an error occured),
FD_ISSET() will return
false
and your function returnsTR_SUCCESS
!? - you
FD_SET(passedInFileDescriptor, &fdset)
, but check on another value:FD_ISSET(mFileDescriptor, &fdset)
. If mFileDescriptor != passedInFileDescriptor at some point, you'll fall into my first assumption.
It should be looking like this:
if (FD_ISSET(passedInFileDescriptor, &fdset))
{
if(rc = readData(readValue) <= 0)
{
result = TR_ERROR;
}
else
{
result = TR_SUCCESS;
}
}
else
{
result = TR_ERROR;
}
No?
(Edit: also, this answer also points the problem of your use of select()
with a bad high_fd value)
Another edit: well, looks like the guys never came back... frustrating.
精彩评论