当前位置: 首页 > news >正文

c++应用网络编程之四Linux常用的网络IO模型

一、网络IO模型的实际应用

在前面学习了基本的网络IO模型,那么这种抽象的网络IO模型如何在实际的编程中应用呢?这其实就是理论与实际如何产生联系的一个过程。在现实世界中,有了理论的指导,下一步就是要把相关的理论如何与具体的实践相结合。一个真正的学习者,恰恰是一个好的应用者。从抽象到实践其实是有一些规律可以遵循的。最基础的办法就是使用一些现有的实践模型,将其在场景中应用并不断的掌握其中的内在情况,不断的适应和修改二者的平衡点。即使最终没有成功的把某种模型与实际场景结合成功,那么也明白了这种场景与这种模型的不匹配的所存,这就是迈向实践过程的第一步。
在Linux的网络IO模型中,常用的也就几种,下面就其进行一下分析和说明。

二、Linux平台下的常用IO模型

这里的Linux其实指是常见的大多数的类Linux平台。在这些平台上,常用的IO网络模型其实主要有以下几个:
1、BIO,同步模型
这种模型,就是最原始的模型。即直接使用网络套接字,按照套接字的流程进行编程。这种编程方式,简单、方便。对于处理一些常见的基础的网络通信,特别是一对一的网络命令通信时,就相当有效。而它的基本应用场景就是,客户端和服务端是单映射,通信数据量较小,通信环境一般是自组网或局域网内。
这种模型非常简单,就不再深入分析了。

2、select IO多路复用模型
在Linux中提供了函数:

int select(int nfds, fd_set *r, fd_set *w, fd_set *e, struct timeval *timeout);

这种模型就是为了解决同步IO的问题,它解决了服务端1:N的问题。即每个服务端可以连接多个客户端而不需要单独的创建线程来控制。select模型的本质其实就是内核处理一个遍历文件描述符数组(fd,网络通信句柄)可读写(就绪)的过程。它适应的场景一般是并发不太高的情况下,而且由于是遍历,所以效率不高。通常select模型默认的扫描数量是1024(32位)或2048(64位)。当然,此数量可以在头文件中自行修改,不过不建议这么做。
其由POSIX定义,所以基本各个平台都会有支持。

3、poll IO多路复用模型

int poll(struct pollfd *fds, nfds_t nfds, int timeout);

这个模型的本质和select模型没有本质区别,都是遍历文件描述数组的过程。只不过在这个模型中采用了链表方式保存文件描述符,故基本上可以理解为没有了select模型中的限制。它的适应场景和select基本一样,虽然从理论上可以用于更高的网络并发,但其实带来的编程复杂度,使其得不偿失。但在一些特定的场景下,如并发很多,但实际活动连接不多的情况下,它还是有用武之地的。
4、epoll IO多路复用模型
epoll比较复杂,它由一组函数epoll_create,epoll_wait,epoll_event 和epoll_ctl等相关操作组成。epoll分为两种触发方式,即LT,Level-Triggered(水平触发)和ET,Edge-Triggered(边缘触发)。LT一般来说适用比较广,常见的epoll编程基本以这种居多,最适合高并发场景,因为虽然叫高并发,但具体到某一个时刻,真正处于活动的则未必非常多。而ET一般适用于处理事件触发这个动作会引起的后果的场景,由于其只动作一次,所以能更好的提高通信效率。它更适合于大数据量的通信。
上面的详细应用细节,会在后面分章节逐一进行分析和应用说明。除此之外,还有其它一些平台比如Solaris的evport,Free BSD中的Kqueue(MacOS),但均不是常用的,这里都不再介绍,有兴趣的可以自己分析一下,其实原理都基本类似。
另外在前面单独分析过最新的IO模型IO_URING模型,这里就不再重复,有兴趣的可以翻看以前的文章“Linux新的IO模型io_uring”。
最后,需要说明的是,这三种IO模型本质上仍然是同步IO,特别是epoll很多人容易将其理解成异步IO,一定要记清楚,它也是同步IO。这也是大多数人都知道的Windows上的IOCP模型要比其效率更高的原因。

三、比较分析

理论上讲select和poll模型基本算是一个水平,它们需要在内核空间和用户空间进行文件描述符的复制,这意味着两种状态空间的切换,代价肯定是大的。所以其不适合于高并发的场景。同时,poll还是一种反复触发机制,即如果发现fd就绪后未处理,则会再次扫描时继续触发。而epoll则是共享内存空间不需要在两种状态空间间进行数据的拷贝交换。
select模型的有处理文件描述符的上限,一般不建议修改;poll虽然没有上限,但处理大量文件句柄时会带来效率的快速降低。而epoll则通过事件触发机制进行回调处理,所以对上限基本不敏感。但如果活跃连接过多导致事件触发频繁,仍然会可能导致性能和效率的问题。在一般情况下epoll可以轻松处理c100k的问题。如果机制的配置升高,则还可以进一步的提高。不过需要注意的是,网络的高并发和高并发处理是两个问题,这个经常被很多人忽视。举一个简单例子即可明白,一个服务端连接了十万个客户端,但只有极少的客户端是活跃的;另外一个服务端连接了十万个客户端但基本都是活跃的。
从开发者普遍的意识上来看,可能epoll的效率最高。但其实则未必,这要看应用场景,比如在连接少(十的量级),但活跃并发高(十个全部在通信且数据量相对较多)时,select和poll模型很有可能比epoll模型效率更高。
大家一定要记住,所以效率一定是相对的而不是绝对的,适合的才是最好的。

四、总结

实事求是,与时俱进,理论联系实际,实践是检验真理的唯一标准…,这些理论每个人可能都会脱口而出。但真正的应用环节呢?可能绝大多数人会有意无意的找各种借口,陈陈相因,因循守旧,更别提创新意识了。只有在实践中深入分析掌握了现有技术的优劣,才可能知晓应用场景下的各种技术不足,才可能产生创新意识。网络编程中这种例子特别多(如io_uring,dpdk),毕竟实际应用的在不断提高对网络技术的要求。而更可怕的是,这种要求不但没有降低还在不断的提高。
网络编程技术是一个计算机编程技术的集大成的方向,是一个软件开发者攀登的高峰。愿与诸君共勉,一同登峰赏景!

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • WPF之URI的使用
  • Linux 各目录
  • MySQL-显示所有错误信息
  • Linux——Shell脚本和Nginx反向代理服务器
  • MCU常见相关术语缩写说明
  • pnpm build打包时占内溢出
  • 【 DHT11 温湿度传感器】使用STC89C51读取发送到串口、通过时序图编写C语言
  • Python 二进制求和
  • 第五章:卷-将磁盘挂载到容器
  • linux环境交叉编译openssl库,以使Qt支持https
  • (二)原生js案例之数码时钟计时
  • 使用ChatGPT来撰写和润色学术论文的教程(含最新升级开桶ChatGpt4教程)​​
  • MySQL事务管理(上)
  • C++ versions less than C++14/11 are not supported.报错
  • vscode 远程 Ubuntu 系统
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • angular2开源库收集
  • Apache的基本使用
  • Cookie 在前端中的实践
  • Fundebug计费标准解释:事件数是如何定义的?
  • java第三方包学习之lombok
  • php中curl和soap方式请求服务超时问题
  • React Native移动开发实战-3-实现页面间的数据传递
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • SQLServer之索引简介
  • webpack入门学习手记(二)
  • 从输入URL到页面加载发生了什么
  • 后端_ThinkPHP5
  • 简单基于spring的redis配置(单机和集群模式)
  • 力扣(LeetCode)965
  • 聊聊redis的数据结构的应用
  • 如何选择开源的机器学习框架?
  • 应用生命周期终极 DevOps 工具包
  • 与 ConTeXt MkIV 官方文档的接驳
  • 再谈express与koa的对比
  • media数据库操作,可以进行增删改查,实现回收站,隐私照片功能 SharedPreferences存储地址:
  • ​linux启动进程的方式
  • ​油烟净化器电源安全,保障健康餐饮生活
  • #ubuntu# #git# repository git config --global --add safe.directory
  • #微信小程序:微信小程序常见的配置传旨
  • #我与Java虚拟机的故事#连载12:一本书带我深入Java领域
  • #在 README.md 中生成项目目录结构
  • (03)光刻——半导体电路的绘制
  • (2024)docker-compose实战 (9)部署多项目环境(LAMP+react+vue+redis+mysql+nginx)
  • (done) ROC曲线 和 AUC值 分别是什么?
  • (二)换源+apt-get基础配置+搜狗拼音
  • (亲测有效)推荐2024最新的免费漫画软件app,无广告,聚合全网资源!
  • (三)Honghu Cloud云架构一定时调度平台
  • (十)DDRC架构组成、效率Efficiency及功能实现
  • (十一)JAVA springboot ssm b2b2c多用户商城系统源码:服务网关Zuul高级篇
  • (十一)图像的罗伯特梯度锐化
  • (贪心) LeetCode 45. 跳跃游戏 II
  • (一)插入排序
  • (转)项目管理杂谈-我所期望的新人
  • (转载)CentOS查看系统信息|CentOS查看命令