面试题答案
一键面试fd_set数据结构的作用
fd_set
是在Unix/Linux系统中用于select
函数的一个数据结构,它用来表示一组文件描述符(file descriptor)。select
函数通过检查fd_set
中各个文件描述符的状态,判断哪些文件描述符已经准备好进行读、写或异常处理操作。这样可以实现同时监听多个文件描述符,提高I/O操作的效率,避免逐个轮询文件描述符带来的性能开销。
相关函数及操作方法
-
FD_SET宏
- 作用:将一个给定的文件描述符添加到
fd_set
集合中。 - 原型:
void FD_SET(int fd, fd_set *set);
- 示例:
#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <arpa/inet.h> #include <string.h> #include <sys/select.h> int main() { fd_set read_fds; FD_ZERO(&read_fds); int sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { perror("socket"); exit(1); } FD_SET(sockfd, &read_fds); // 后续可以使用select函数基于read_fds进行操作 close(sockfd); return 0; }
- 作用:将一个给定的文件描述符添加到
-
FD_CLR宏
- 作用:从
fd_set
集合中移除一个给定的文件描述符。 - 原型:
void FD_CLR(int fd, fd_set *set);
- 示例:
// 假设之前已经设置了read_fds集合 int sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { perror("socket"); exit(1); } FD_SET(sockfd, &read_fds); // 假设要移除sockfd FD_CLR(sockfd, &read_fds); close(sockfd);
- 作用:从
-
FD_ISSET宏
- 作用:检查一个给定的文件描述符是否在
fd_set
集合中。 - 原型:
int FD_ISSET(int fd, fd_set *set);
- 返回值:如果文件描述符
fd
在集合set
中,返回非零值;否则返回0。 - 示例:
if (FD_ISSET(sockfd, &read_fds)) { // sockfd在read_fds集合中,执行相关读操作等 char buffer[1024]; ssize_t bytes_read = recv(sockfd, buffer, sizeof(buffer), 0); if (bytes_read > 0) { buffer[bytes_read] = '\0'; printf("Received: %s\n", buffer); } }
- 作用:检查一个给定的文件描述符是否在
-
FD_ZERO宏
- 作用:清空
fd_set
集合,使其不包含任何文件描述符。 - 原型:
void FD_ZERO(fd_set *set);
- 示例:
fd_set read_fds; FD_ZERO(&read_fds); // 然后可以使用FD_SET等宏添加文件描述符到read_fds集合
- 作用:清空
在使用select
函数时,通常会初始化fd_set
集合(使用FD_ZERO
),添加感兴趣的文件描述符(使用FD_SET
),调用select
函数等待文件描述符准备好,然后通过FD_ISSET
检查哪些文件描述符准备好了,进行相应的I/O操作。如果某个文件描述符不再需要监听,可以使用FD_CLR
将其从集合中移除。