select函数是什么
select函数可以将多个文件描述符集中到一起统一监视,监视项分为三类(接收,传输,异常)。为避免阻塞,该函数也有超时时间参数。
/* Check the first NFDS descriptors each in READFDS (if not NULL) for read
readiness, in WRITEFDS (if not NULL) for write readiness, and in EXCEPTFDS
(if not NULL) for exceptional conditions. If TIMEOUT is not NULL, time out
after waiting the interval specified therein. Returns the number of ready
descriptors, or -1 for errors.
This function is a cancellation point and therefore not marked with
__THROW. */
extern int select (int __nfds, fd_set *__restrict __readfds,
fd_set *__restrict __writefds,
fd_set *__restrict __exceptfds,
struct timeval *__restrict __timeout);
__nfds:监视对象文件描述符数量,即监视范围。只需将需要监视的最大的文件描述符加1即可,加1是因为文件描述符从0开始。
__readfds:关注接收事件的fd_set文件描述符组
__writefds:关注传输事件的fd_set文件描述符组
__exceptfds:关注异常事件的fd_set文件描述符组
__timeout:超时时间,防止陷入阻塞
返回值:发生错误返回-1,超时返回0。
因发生关注的事件返回时,返回大于0的值,该值为发生关注事件的文件描述符数
多个文件描述符的集合用fd_set类型设置,fd_set的最左端的位表示文件描述符0,当该位值为1时表示监视该文件描述符。
有相关宏定义用于操作该变量。
/* Access macros for `fd_set'. */
FD_SET(int fd, fd_set *fdsetp) 在参数fdsetp指向的变量中注册文件描述符fd的信息
FD_CLR(int fd, fd_set *fdsetp) 在参数fdsetp指向的变量中清除文件描述符fd的信息
FD_ISSET(int fd, fd_set *fdsetp) 若fdsetp中有fd的信息,则返回true
FD_ZERO(fd_set *fdsetp) 设置fdsetp变量的所有位为0
2.select函数怎么用
注意:
1.在调用select函数后, tv_sec以及tv_usec的值会被替换为超前剩余时间, 循环中需注意
2.在调用select函数后, 除发生变化的文件描述符对应位外, 其他位将初始化为0
#include <stdio.h>
#include <sys/time.h>
#include <sys/select.h>
#include <unistd.h>
#define BUF_SIZE 100
int main(){
fd_set reads, temps;
FD_ZERO(&reads);
FD_SET(0, &reads);//0为标准输入文件描述符, 监视标准输入
struct timeval time;
//time.tv_sec = 3;//在调用select函数后, tv_sec以及tv_usec的值会被替换为超前剩余时间
//time.tv_usec = 0;
int str_len;
int res;
char buf[BUF_SIZE];
while (1){
temps = reads;//在调用select函数后, 除发生变化的文件描述符对应位外, 其他位将初始化为0, 这是为了记住初始值
time.tv_sec = 3;//在调用select函数后, tv_sec以及tv_usec的值会被替换为超前剩余时间
time.tv_usec = 0;
res = select(1, &temps, NULL, NULL, &time);
if(res == -1){
printf("select error\n");
break;
} else if(res == 0){
printf("select timeout\n");
} else{
if(FD_ISSET(0, &temps)){
str_len = read(0, buf, BUF_SIZE);
buf[BUF_SIZE] = 0;
printf("message from console:%s", buf);
}
}
}
return 0;
}