面试题答案
一键面试数据结构
- fd_set:用于存储文件描述符集合。在Linux下,它通常是一个位数组,每一位对应一个文件描述符。可以使用
FD_ZERO
、FD_SET
、FD_CLR
和FD_ISSET
等宏来操作这个集合。 - timeval:用于设置select等待的超时时间。结构定义如下:
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
主要操作步骤
- 初始化文件描述符集合:
- 使用
FD_ZERO
宏清空一个fd_set
变量,例如fd_set read_fds; FD_ZERO(&read_fds);
。 - 使用
FD_SET
宏将需要检测的文件描述符添加到相应的集合中,如FD_SET(sockfd, &read_fds);
,这里sockfd
是要检测读事件的套接字文件描述符。
- 使用
- 设置超时时间:
- 定义一个
timeval
结构体变量并赋值,指定等待的秒数和微秒数。例如:
- 定义一个
struct timeval timeout;
timeout.tv_sec = 5;
timeout.tv_usec = 0;
如果希望无限等待,可以将timeval
指针设为NULL
。
3. 调用select函数:
int ret = select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
- `nfds`:是所有文件描述符集合中最大文件描述符加1。
- `readfds`、`writefds`、`exceptfds`:分别是要检测读事件、写事件和异常事件的文件描述符集合。
- 返回值`ret`:
- 大于0:表示有事件发生,`ret`的值是发生事件的文件描述符的总数。
- 等于0:表示等待超时,没有事件发生。
- 小于0:表示发生错误,`errno`会被设置以指示错误类型。
4. 检查事件:
- 使用FD_ISSET
宏检查某个文件描述符是否在发生事件的集合中。例如:
if (FD_ISSET(sockfd, &read_fds)) {
// sockfd上有读事件发生,进行相应处理
}