我遇到了 FD_SET
的问题。我在 Linux 中使用套接字 CAN 方法和使用 recvfrom
访问 CAN。由于是阻塞调用,所以我想使用select
系统调用。我的程序挂起@FD_SET
宏。它适用于 FD_CLR
宏。
代码:
FD_ZERO(&readfd);
printf("\n 1.1");
FD_CLR(s, &readfd);
printf("\n 1.2");
FD_SET(sockaddr,&readfd); //hangs here
printf("\n 1.3");
输出:
1.1
1.2
在那之后没有得到任何东西......
即使sockaddr
值为3(小于FD_SETSIZE
= 1024);
我可以将 FD_SET
应用于套接字可以接近套接字吗?
可能是什么原因?
最佳答案
它不太可能卡在 FD_SET()
处。更有可能的是 stdout
是一个终端,在这种情况下,您的 C 库会进行行缓冲,以便仅在看到终止换行符后才将每一行发送到终端。
尝试做例如printf("1.3\n")
代替(或者只是 puts("1.3")
,这是一样的,而且更简单)。您也可以使用调试器。
(如果 stdout
是一个常规文件,在打印“1.3”之后对其执行 fflush(stdout)
5gon12eder 在评论中建议。无论 stdout
是终端还是常规文件(将使用 block 缓冲),fflush()
都会工作,因此它是一个更好的解决方案。另一种选择是使用 stderr
,它默认是无缓冲的。)
FD_ZERO(&readfd)
之后的 FD_CLR(s, &readfd)
是多余的。 FD_ZERO()
已经清除了 fd_set
readfd
。
至于真正的问题(挂起):
你在 FD_ZERO(&readfd)
之后执行 FD_CLR(s, &readfd)
可能表明你误解了 select(2)
有效。如果您在这些行之后使用 select(FD_SETSIZE, &readfd, NULL, NULL, NULL)
,那么结果将是您仅一直在等待sockaddr
文件描述符变得可读(读取时不阻塞)。
还要确保 readfd
是一个 fd_set
并且 s
和 sockaddr
是描述符(由例如 socket(2)
和 open(2)
)。否则,事情就没有意义了。
关于c - 程序在 Linux 用户空间的 FD_SET 宏处挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29143584/