目录

  • 一、学习的知识点
    • 1 五种 I/O
      • 1.1 阻塞式I/O
      • 1.2 非阻塞式I/O
      • 1.3 I/O复用(select 和pool)
        • 1.3.1 select 文件描述符的管理
        • select 缺点
        • epoll
      • 1.4 信号驱动I/O
      • 1.5 异步I/O
  • 二、上课没有听懂或者没有理解的地方
  • 三、当天学习的收获

一、学习的知识点

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, NULL, NULL, NULL); //n个文件描述符产生事件//select返回有两种情况:1 有新客户端连接  2 文件描述符有数据可读//情况1 如果select返回后 rset存放的是listen_fd 说明是监听套接字产生了可读事件 意味着有新的客户端的连接cout << "select is return .." << n << endl;//有可能是新的客户端连接上来 rset里面的文件描述符是不是socket_fdif (FD_ISSET(listen_fd, &rset)) //判断 listen_fd是否在集合里面{//证明有新的客户端连接进来//4. 如果没有客户端完成三次握手,程序会阻塞在accept cout << "wait" << endl;//此时的accept不阻塞 直接连接int con_fd = accept(listen_fd, (struct sockaddr*)&cli_add, &add_len);if (con_fd == -1)ERR_EXT("accept");printf("\r\n con_fd: %d client connected %s:%d \r\n", con_fd, inet_ntoa(cli_add.sin_addr), ntohs(cli_add.sin_port));//con_fd 表示新的客户端 这个客户端立马加入select 管理FD_SET(con_fd, &allset);//把新的客户端文件描述符放入容器allfd.push_back(con_fd);if (con_fd > maxfd)maxfd = con_fd;}else //否则是收到消息 rest变成产生可读事件对应的文件描述符 此时要 read 取出数据 否则会一直触发select{//read取走数据 到底是哪个for (it = allfd.begin(); it != allfd.end(); it++){if (FD_ISSET(*it, &rset)){int fd = *it;int ret = read(fd, buff, 1024);if (ret == 0){cout << "client is off  fd=" << *it << endl;//把这个客户端从集合删除FD_CLR(fd, &allset);allfd.erase(it);break;}if (ret > 0){cout << "read:" << buff << endl;write(fd, buff, 1024);bzero(buff, 1024);break;}}}cout << "new message.." << endl;}}

epoll

与select相比,优点是 不需要遍历fd 直接读取到产生事件的fd

  • 函数原型:int epoll_create(int size)

    • 功能:创建一个epoll句柄 管理器 统一管理文件描述符
    • 参数:
  • 返回值:成功返回文件描述符 失败返回 -1
  • 函数原型:int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

    • 功能:将fd以 op(增加 修改 删除) 的方式 给 epfd 管理
    • 参数:
  • 返回值:成功返回文件描述符 失败返回 -1
struct epoll_event eventarry[5];int epo = epoll_create(10);//创建一个EPOLL句柄 创建一个管理器struct epoll_event event;event.events = EPOLLIN;//表示 关心他的可读事件event.data.fd = listen_fd; //data结构体 char buff[1024] = { 0 };//表示把listen_fd添加到epo管理  event为listen_fd的属性 包含管理的方式 关心listen_fd的可读事件 并且带一个数据:这个数据放fd epoll_ctl(epo, EPOLL_CTL_ADD, listen_fd, &event);while (1){//int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);epoll_wait(epo, eventarry, 5, -1);  //会阻塞  参数2 存放事件的数组  放epoll返回后产生事件的结构体  参数3 不能大于 epoll_create 的参数  参数4 超时  不关心//假如 一个文件描述符产生事件 相应的属性结构体 就会放入 参数2 的数组中   if (eventarry[0].data.fd == listen_fd){//有新的客户端连接int con_fd = accept(listen_fd, (struct sockaddr*)&cli_add, &add_len);struct epoll_event new_event;new_event.events = EPOLLIN;//表示 关心他的可读事件new_event.data.fd = con_fd; //data结构体 epoll_ctl(epo, EPOLL_CTL_ADD, con_fd, &new_event); //把 con_fd加入 epoll 管理}else{int fd = eventarry[0].data.fd;read(fd, buff, 1024);cout << "read:" << buff << endl;}}

1.4 信号驱动I/O

1.5 异步I/O

二、上课没有听懂或者没有理解的地方

三、当天学习的收获

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

  1. select、poll、epoll的文件描述符上限问题

    select.poll.epoll是三个常用的I/O复用,之前使用过程中一直没很深入思考,只知道①select有文件描述符上限 ②poll是select的改进,去掉了文件描述符上限 ③epoll是前两 ...

  2. 【C/C++服务器开发】文件,文件描述符,I/O多路复用,select / poll / epoll 详解

    文章目录 一.前言 1.文件的概念 2.文件描述符和文件指针 文件描述符 文件描述符和文件指针的区别 文件描述符太多了怎么办 二.I/O多路复用 1.I/O多路复用的由来 不要打电话给我,有需要我会打 ...

  3. select中文件描述符上限为什么是1024?

    一.两个1024 select中存放文件描述符的数组大小FD_SETSIZE为1024 进程的文件描述符上限默认是1024,正是因为这个原因,select设计时才把数组大小设计为1024 二.问题来了 ...

  4. Select()系统调用及文件描述符集fd_set的应用

    在网络程序中,一个进程同时处理多个文件描述符是很常见的情况.select()系统调用可以使进程检测同时等待的多个I/O设备,当没有设备准备好时,select()阻塞,其中任一设备准备好时,select ...

  5. linux内核中的文件描述符(三)--fd的回收

    linux内核中的文件描述符(三)--fd的回收 Kernel version:2.6.14 CPU architecture:ARM920T Author:ce123(http://blog.csd ...

  6. io多路复用的原理和实现_IO多路复用的三种机制:select 、poll 、epoll

    目录 概述 IO多路复用本质 IO多路复用的优势 IO多路复用Select机制 IO多路复用Poll机制 IO多路复用Epoll机制 select,poll,epoll机制区别总结 php7进阶到架构 ...

  7. Linux select/poll/epoll

    参考地址:https://www.jianshu.com/p/fe54ca4affe8 本文讨论的背景是Linux环境下的network IO. 一. 概念说明 在进行解释之前,首先要说明几个概念: ...

  8. IO多路复用及select poll epoll讲解

    https://blog.csdn.net/weixin_43367828/article/details/84676775 https://www.jianshu.com/p/6a684546477 ...

  9. select poll epoll

    一 虚拟存储器 一个作业在运行之前,没有必要把全部作业装入内存,而仅将那些当前要运行的 那部分页面或段,先装入内存便可以启动运行,其余部分暂时驻留磁盘 程序在运行时,如果他所要访问的页面或者端已调入内 ...

最新文章

  1. list保留小数位数
  2. gulp.js 的安装以及使用
  3. python3精要(32)-生成器表达式
  4. linux inotifywait脚本,使用inotify/fswatch构建自动监控脚本
  5. arch linux 入门,arch linux 从来就不是给新手入门用的
  6. Spark初识-弹性分布式数据集RDD
  7. python变量和对象的关系_Python变量与对象引用的区别
  8. javascript正则表达式一
  9. SQL:两种获取时间类型日期部分的方法
  10. SAE J1939协议(二)
  11. java基本数据从低到高_java基本数据类型之间的转换
  12. socket里sendto()函数
  13. 完整版第四方Oreo易支付源码+28K易支付源码
  14. 自动点击android按钮,Android实现自动点击无障碍服务功能的实例代码
  15. 真香啊,Python 轻松制作制作GIF动图
  16. MySQL-14使用子查询-必知必会
  17. DZone每日必读-News:2022 年 Java 开发:预测和选定趋势
  18. 【回溯法】机器零件加工-最优加工顺序
  19. Makefile 书写
  20. Android验证码倒计时实现方式总结

热门文章

  1. golang map源码分析
  2. 阿里1682亿背后的协同研发云——云效公共云正式商业化
  3. 轻松搞定对容器实例日志设置定期清理和回卷
  4. 每天学一点Scala之 高阶函数 flatten
  5. 创维37K05HR黑屏有声音故障维修
  6. [Ubuntu]使用dict/dictd英文字典
  7. 公式 有效值_纯电阻电路电功率公式
  8. 为什么使用mq?具体的使用场景是什么?
  9. 通道Channel-使用NIO 写入数据
  10. 为什么任何对象都可以实现锁