select函数
时间: 2023-11-11 14:06:42 浏览: 40
select 函数是用于在多个输入流中选择准备好进行读取操作的那个流,并将其返回。在网络编程中,它通常被用来同时监听多个客户端的连接请求。语法如下:
```c
#include <sys/select.h>
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
```
参数说明:
- nfds: 等待的文件描述符个数(最大文件描述符值加1)
- readfds: 可读文件描述符集合
- writefds: 可写文件描述符集合
- exceptfds: 异常文件描述符集合
- timeout: 超时时间,可以是NULL(表示一直等待),也可以指定一个时间间隔
函数返回值:
- 成功时返回已经准备好的文件描述符总数;
- 超时返回0;
- 失败返回-1,并设置errno。
注意事项:
- select 函数会直接修改参数集合,因此每次调用前需要重新初始化。
- select 函数的返回值只表示当前状态,与之前的状态无关,因此需要每次重新调用。
示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/select.h>
#define BUF_SIZE 1024
int main()
{
int fd1, fd2; // 两个文件描述符
fd_set readfds; // 读文件描述符集合
struct timeval timeout; // 超时时间
char buf[BUF_SIZE]; // 读取缓冲区
// 打开两个文件描述符
fd1 = open("file1.txt", O_RDONLY);
fd2 = open("file2.txt", O_RDONLY);
while (1) {
FD_ZERO(&readfds); // 清空读文件描述符集合
FD_SET(fd1, &readfds); // 将fd1加入读文件描述符集合
FD_SET(fd2, &readfds); // 将fd2加入读文件描述符集合
// 设置超时时间为5秒
timeout.tv_sec = 5;
timeout.tv_usec = 0;
// 等待文件描述符准备好
int ret = select(fd2 + 1, &readfds, NULL, NULL, &timeout);
if (ret < 0) {
perror("select error");
break;
} else if (ret == 0) {
printf("timeout\n");
continue;
}
// 读取准备好的文件描述符
if (FD_ISSET(fd1, &readfds)) {
read(fd1, buf, BUF_SIZE);
printf("read from file1: %s\n", buf);
}
if (FD_ISSET(fd2, &readfds)) {
read(fd2, buf, BUF_SIZE);
printf("read from file2: %s\n", buf);
}
}
// 关闭文件描述符
close(fd1);
close(fd2);
return 0;
}
```
这个示例程序监听了两个文件描述符,每次等待5秒钟。如果其中一个文件描述符准备好了,就读取其中的内容。如果超时了,就重新等待。