Linux环境下select函数

select函数

场景:

终端即接收来自标准输入的信息(fd = 0)并作出,也接受listen套接字(fd = 3)的信息并创建对应的已连接描述符

作用:

监听多个文件描述符

相关函数定义:

/* According to POSIX.1-2001 */
#include <sys/select.h>

/* According to earlier standards */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
struct timeval{
    long tv_sec;//秒
    long tv_usec;//微秒
}//已经在头文件定义好了的,直接用就行
int select(int nfds, fd_set *readfds, fd_set *writefds,
           fd_set *exceptfds, struct timeval *timeout);
/**
返回值有两:int和readfds(fd_set的指针)
int:准备好读的文件描述符个数,出错返回-1
readfds:准备好读的文件描述符集合
*/
void FD_CLR(int fd, fd_set *set);    
int  FD_ISSET(int fd, fd_set *set);
void FD_SET(int fd, fd_set *set);
void FD_ZERO(fd_set *set);

参数说明:

nfds:

表示集合中所有文件描述符的范围,即所有文件描述符的最大值+1

readfds:

待读文件描述符集合

怎么理解这个集合?传入一个fd_set,只有在fd位置为1的文件描述符才会被监听有无写入

比如fd = 0,flag = 1(stdin);

​ fd = 1,flag = 0;

​ fd = 2,flag = 0;

​ fd = 3,flag = 1(监听套接字描述符);

select只会监听fd = 0和fd = 3的文件是否准备好可以读了,只要有一个准备好了,select就会停止阻塞,返回,进程继续执行

操作集合fd_set的函数:
void FD_CLR(int fd, fd_set *set);//清除某一个被监视的文件描述符。(fd = fd的位置设为0)
int  FD_ISSET(int fd, fd_set *set);//测试一个文件描述符是否是集合中的一员(fd = fd的位置是否为1)
void FD_SET(int fd, fd_set *set);//添加一个文件描述符,将set中的某一位设置成1;(fd = fd的位置设为1)
void FD_ZERO(fd_set *set);//清空集合中的文件描述符,将每一位都设置为0;(所有位置设为0)

writefds:NULL

exceptfds:NULL

timeout:

一个struct timeval指针,设置select的最大阻塞时长,如果为null,则会一直阻塞

返回值说明:

返回值有两:int和readfds(fd_set的指针)

int:准备好读的文件描述符个数,出错返回-1

readfds:准备好读的文件描述符集合

实例:

i/o多路复用服务器:

p686页代码、p688页代码

家庭作业12.32:

//-------------------------------main.cpp---------------------------
#include<stdio.h>
#include<iostream>
#define MAXLINE 1000
using namespace std;
char* tfgets_select(char * s,int size,FILE* stream);
int main(){
    char buf[MAXLINE];
    if (tfgets_select(buf, MAXLINE, stdin) == NULL)
        printf("BOOM!\n");
    else
        printf("%s", buf);
    return 0;
}
//------------------------------tfget.cpp-------------------------
#include<stdio.h>
#include<sys/select.h>
using namespace std;
//char* tfgets_proc(char * s,int size,FILE* stream){
//}
char* tfgets_select(char * s,int size,FILE* stream){
    fd_set read_set,ready_set;
    struct timeval t;
    //初始化读集合
    FD_ZERO(&read_set);
    FD_SET(0,&read_set);
    //初始化最大阻塞时间
    t.tv_sec = 5;
    t.tv_usec = 0;
    //用ready_set复制read_set作为参数,因为ready_set还会作为返回值
    ready_set = read_set;
    select(0+1,&ready_set,NULL,NULL,&t);
    if(FD_ISSET(0,&ready_set)){
        return fgets(s, size, stream);
    }
    else{
        return NULL;
    }
}
//---------------------------makefile----------------------------
prog:main.o tfgets.o
	g++ -o prog main.o tfgets.o
main.o:main.cpp
	g++ -c main.cpp
tfgets.o:tfgets.cpp
	g++ -c tfgets.cpp
clean:
	rm -rf prog
	rm -rf *.o

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值