select()块,而不是返回超时

select() blocks instead of returning a timeout

本文关键字:返回 超时 select      更新时间:2023-10-16

作为背景,我正在编写一个多线程linux服务器应用程序。每个子进程都有一个与其关联的连接,并使用select()查看套接字上是否有等待读取的数据。

我做了一些搜索,这一次我找不到任何帮助来解决这个问题。

第一次真正发布到堆栈溢出,所以我很抱歉,如果我的格式是垃圾。

//this first line switches my connection to non-blocking.
//select() still fails whether or not this line is in.
fcntl(ChildConnection -> newsockfd, F_SETFL, 0);    
struct timeval tv;
fd_set readfds; 
FD_ZERO(&readfds);
FD_SET(ChildConnection -> newsockfd, &readfds);
tv.tv_sec = 3; //3 seconds of waiting maximum. Changing this does nothing.
tv.tv_usec = 0;
printf("-DEBUG: Child, About to select() the newsockfd, which is %i. readfds is %i.n", ChildConnection -> newsockfd, readfds);
//if I feed this a bad descriptor (-1 or something) on purpose, it DOES return -1 though.
int result = select(ChildConnection -> newsockfd + 1, &readfds, NULL, NULL, &tv);
//this commented out line below doesn't even time out.
//int result = select(0, NULL, NULL, NULL, &tv);
printf("-DEBUG: Child, Just  select()ed. result is %i. Hopefully that was >= 0.", result);
if (result < 0)
{
 DisplayError("ERROR using select() on read connection in MotherShip::HandleMessagesChild: ");
}
else if (result > 0) // > 0 means there is data waiting to be read
{
/* <--- Snipped Reading Stuff here ---> */      
}
//so if the code gets here without a result that means it timed out.

不幸的是,第二个打印行(表示已选中)永远不会打印。有人知道发生了什么吗?或者有人建议我尝试调试这个吗?

您在其他地方有阻塞条件。让你的select()代码先在一个小的测试设备中工作,然后移植它。你在代码中的评论"下面的注释行甚至没有超时"是可验证的错误:

$ cat test.c
#include <stdio.h>
#include <sys/select.h>
int main()
{
    struct timeval tv;
    tv.tv_sec = 3;
    tv.tv_usec = 0;
    select(0, NULL, NULL, NULL, &tv);
    return 0;
}
$ gcc -o test test.c
$ time ./test
real    0m3.004s
user    0m0.000s
sys 0m0.000s

或者,尝试将调试器附加到挂起的进程,并查看它被阻止的位置。或者在strace()等中观看…