大多数情况下,这段代码运行得很好。但有时当可执行文件运行一段时间后,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;
}
}
答案 0 :(得分:1)
请注意,“select”的某些实现严格适用于规范: “nfds是三组中任何一组中编号最大的文件描述符,加1”。 所以,你最好用“passInFileDescriptor + 1”作为第一个参数来改变“1”。 我不知道这是否可以解决你的问题,但至少你的代码变得更加......呃...“传统的”;)
再见
答案 1 :(得分:1)
在某些操作系统上,调用timeout
时会修改select
以反映未睡眠的时间。在您的示例中,您似乎不再使用timeout
,但请确保在调用select
之前每次重新初始化为5秒。
答案 2 :(得分:1)
我遇到了同样的问题,它在Windows上运行正常但在linux上运行不正常,我将maxfd设置为最后一个套接字+ 1.它在长时间运行后会定期发生。我在接受时接听连接,然后第一次选择定期选择超时。
答案 3 :(得分:0)
看看这段代码:
if (FD_ISSET(mFileDescriptor, &fdset))
{
if(rc = readData(readValue) <= 0)
{
result = TR_ERROR;
}
} else {
result = TR_SUCCESS;
}
这里有两件事困扰我:
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;
}
没有?
(编辑:同样,this answer也指出了您使用 high_fd 值错误的select()
的问题
另一个编辑:好吧,看起来这些家伙再也没有回来......令人沮丧。