020303阶段三 I/O复用 select和epoll的文件描述符管理

一、学习的知识点

man 2 属于系统调用
read 系统调用 先到内核空间(操作系统层)取数据 ,存放到 buff(应用层 用户空间)

1 五种 I/O

1.1 阻塞式I/O

通过read系统调用 到内核空间读取数据到用户空间,没有数据读取时 会阻塞。占用资源

1.2 非阻塞式I/O

阻塞和非阻塞是针对文件描述符来说。
通过 fcntl 函数设置 文件描述符的属性 默认为阻塞 可以设置为非阻塞 fd ctrl

1.3 I/O复用(select 和pool)

对I/O的操作只有 读 写,

1.3.1 select 文件描述符的管理

select 相当于一个管家 管理和socket有关的所有文件描述符 select只用一个进程就可以实现群聊服务器
select要知道当前进程的最大文件描述符是多少
管什么:暂时只管理 文件描述符的可读事件 可读事件(新的客户端连接、 文件描述符有数据可读包括客户端下线)
管理?文件描述符
会知道新客户端连按時文件描述符
会知道有数据需要去取的文件描述符
会知道下线的文件描述符

函数等待集合中产生可读事件的文件描述符。连接一个客户端 集合的值会变,哪个文件描述符产生可读事件 集合就变成几。 fd_ set是一个输入输出参数

  • int select(int nfds, fd_ set *readfds, fd_ set *writefds,fd set *exceptfds, struct timeval *t imeout) ;
    • 参数1:当前进程 最大文件描述符的数值是多少
    • 参数2:文件描述符的可读事件集合
    • 参数3 可写
    • 参数4 异常
  • 返回值:有几个文件描述符产生事件 就返回几
select 缺点

通过轮询查找文件描述符 如果文件描述符太多 效率就不高 没有可读事件产生会等待 select阻塞

对文件描述符的集合操作

  1. void FD_ CLR(int fd, fd_ set *set); 从集合删除某个文件描述符
  2. int FD_ ISSET(int fd, fd_ set *set); 判断集合中是否包含某个文件描述符
  3. void FD SET(int fd, fd_ set *set); 吧文件描述符加入集合
  4. void FD_ ZERO(fd_ set *set); 把集合清空
	int maxfd = listen_fd;
	fd_set rset;  //文件描述符集合
	fd_set allset; //放最新最全的文件描述符
	
	FD_ZERO(&allset);
	FD_ZERO(&rset);
	FD_SET(listen_fd, &allset);//吧 listen_fd放入allset 里面  交给select 监管
	cout << "select is wait..." << endl;
	char buff[1024] = {
   
    0 };
	while (1)
	{
   
   
		rset = allset; //因为select每返回一次 rset存放的都是产生事件的文件描述符的集合 其他的文件描述符被丢弃 
						//所以每返回一次 都要把最全的集合给他
		//参数1 fd数量 比如最大文件描述符为6 则轮询0-6 7个文件描述符  一旦select返回 rset会变成已经产生可读事件的文件描述符的集合 
		//如果两个文件描述符产生事件 就变成两个对应的文件描述符的集合
		int n = select(maxfd + 1, &rset
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值