linux select
ddatsh
标准输入上等待输入事件
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
int main() {
fd_set read_fds; // 读文件描述符集合
struct timeval timeout; // 超时时间结构体
int max_fd = 1; // 文件描述符的最大值
int result;
while (1) {
FD_ZERO(&read_fds); // 清空文件描述符集合
FD_SET(STDIN_FILENO, &read_fds); // 将标准输入添加到文件描述符集合
timeout.tv_sec = 5; // 设置超时时间为5秒
timeout.tv_usec = 0;
// 使用 select 函数检查文件描述符集合上是否有可读事件
result = select(max_fd, &read_fds, NULL, NULL, &timeout);
if (result == -1) {
perror("select");
exit(EXIT_FAILURE);
} else if (result == 0) {
// 超时,可以在这里添加相应的处理逻辑
printf("Timeout occurred!\n");
fflush(stdout);
} else {
// 文件描述符上有可读事件发生
if (FD_ISSET(STDIN_FILENO, &read_fds)) {
char buffer[1024];
// 从标准输入读取数据
ssize_t bytesRead = read(STDIN_FILENO, buffer, sizeof(buffer));
if (bytesRead == -1) {
perror("read");
exit(EXIT_FAILURE);
} else if (bytesRead == 0) {
// EOF,表示输入结束
printf("End of file reached. Exiting...\n");
break;
} else {
// 处理读取到的数据,这里简单地将其输出
printf("Read from stdin: %.*s", (int)bytesRead, buffer);
fflush(stdout);
}
}
}
}
return 0;
}
- fd_set为 bitmap 结构,且有长度为 1024 的限制
// select.h
typedef struct {
...
__fd_mask __fds_bits[__FD_SETSIZE / __NFDBITS];
...
} fd_set;
/* Number of descriptors that can fit in an `fd_set'. */
#define __FD_SETSIZE 1024
-
fdset 无法做到重用,每次循环必须重新创建
-
频繁的用户态和内核态拷贝,性能开销较大
-
需要对文件描述符表进行遍历,O(n) 的轮询时间复杂度