网络IO

先确定一下范围,我们讨论的都是网络IO,现阶段计算机早已经从CPU密集型转换成网络IO密集型,所以网络io的类型对于服务响应而言更重要。

五种IO模型

依据Unix的IO分类,网络IO分为五类

  • 阻塞IO(BlockingIO
  • 非阻塞IO(Non-Blocking IO
  • IO多路复用( IO Multiplexing
  • 信号驱动IO(signal driven IO
  • 异步IO(async IO

内核态和用户态

可见另一篇文章

网络IO的两阶段阶段

  1. 等待网卡读就绪 —> 将网卡数据复制奥内核缓冲区
  2. 将内核缓冲区的数据复制到用户空间

其中:第一阶段主要用来区分是否是阻塞IO

阻塞与非阻塞

进行一个IO操作之后,无论是否有数据、是否就绪,是否会立刻返回而不阻塞用户进程的逻辑。

当用户进程发出read操作时,如果kernel中的数据没有准备好,不会block用户进程,而是返回一个EAGAIN err。从用户的角度而言,发起一个读操作,不需要等待,马上得到了一个结果。

一旦kernel的数据准备好了,收到用户进程的一个systemcall,就会马上把数据拷贝到用户内存,然后返回。

同步与异步

第二阶段,内核将数据拷贝到用户空间是否是同步进行的,决定是否是异步IO;除了aync IO以外其他都是同步的IO模型。

面试回答

概述

IO多路复用实际就是select/poll/epoll这些多路选择器,使用一个线程同时监听多个文件描述符(fd_set), I/O事件,阻塞等待并且在某个文件描述符可读写时收到通知。linux在处理网络IO连接时的优化,复用的不是I/O连接,而是复用的是线程,让一个线程处理多个连接。

select/poll/epoll

选择器 运行逻辑 特点 缺点
select 1.最大并发数限制; 2.每次调用select,需要把fd_set集合拷贝到内核态;3.性能衰减严重
poll poll与select类似,只是没有最大并发数限制
epoll

select

#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h> int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); // 和 select 紧密结合的四个宏:
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);

运行逻辑

fd_set如果是1 字节byte, 1byte = 8bit,每一个bit可以表示一个文件描述符fd,则1byte的fd_set最大可以对应8个fd

  1. 执行 FD_ZERO(&set), 则 set 用位表示是 0000,0000
  2. 若 fd=5, 执行 FD_SET(fd, &set); 后 set 变为 0001,0000(第 5 位置 为 1)
  3. 再加入 fd=2, fd=1,则 set 变为 0001,0011
  4. 执行 select(6, &set, 0, 0, 0) 阻塞等待
  5. 若 fd=1, fd=2 上都发生可读事件,则 select 返回,此时 set 变为 0000,0011 (注意:没有事件发生的 fd=5 被清空)

特点

  1. 可以监控的文件描述符个数取决于 sizeof(fd_set)的值。如果 sizeof(fd_set) = 512, 每个bit表示一个文件描述符, 512 * 8 = 4096。
  2. 需要拷贝 fd_set,转换成一个array
  3. 需要循环fd_set,线性扫描整个fd_set

缺点

epoll

epoll是Linux Kernel 2.6之后引入的IO事件驱动技术,本质上还是一个线程处理所有链接的等待消息准备好IO事件。但是 当数十万的并发连接存在时,可能每一毫秒猪油数百个活跃的链接,同时其余数十万连接在这一毫秒是非活跃的,而select&poll的使用方法是 返回的活跃链接 == select(全部带监控的连接)

高频调用的接口是select()方法,而这个方法任何轻微的效率损失都会被高频两个字放大。epoll解决了这个问题.

#include <sys/epoll.h>
int epoll_create(int size); // int epoll_create1(int flags);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

epoll的工作原理如下图:

  • epoll_ctl 来插入和删除一个fd,实现从用户态到内核态的拷贝,确保每一个fd只在生命周期一次拷贝。
  • epoll使用红黑树存储所有监控的fd,红黑树的时间复杂度O(logN)。
  • 每一个fd有一个关键步骤:fd回合相应的设备(网卡、硬盘)驱动程序建立一个回调关系,在fd相应的时间出发之后,内核就会调用这个回调函数,ep_poll_callback,这个回调函数会把fd添加到fdllist的双向链表(就绪列表之中)epoll_wait这个就是检查是否有就绪的fd,所以非常高效。

Linux面试题2:网络IO模型 & IO多路复用的更多相关文章

  1. Linux 网络编程的5种IO模型:多路复用(select/poll/epoll)

    Linux 网络编程的5种IO模型:多路复用(select/poll/epoll) 背景 我们在上一讲 Linux 网络编程的5种IO模型:阻塞IO与非阻塞IO中,对于其中的 阻塞/非阻塞IO 进行了 ...

  2. IO 模型 IO 多路复用

    IO 模型 IO 多路复用 IO多路复用:模型(解决问题的方案) 同步:一个任务提交以后,等待任务执行结束,才能继续下一个任务 异步:不需要等待任务执行结束, 阻塞:IO阻塞,程序卡住了 非阻塞:不阻 ...

  3. 五种网络IO模型以及多路复用IO中select/epoll对比

    下面都是以网络读数据为例 [2阶段网络IO] 第一阶段:等待数据 wait for data 第二阶段:从内核复制数据到用户 copy data from kernel to user 下面是5种网络 ...

  4. 【经典】5种IO模型 | IO多路复用

    上篇回顾:静态服务器+压测 3.2.概念篇 1.同步与异步 同步是指一个任务的完成需要依赖另外一个任务时,只有等待被依赖的任务完成后,依赖的任务才能算完成. 异步是指不需要等待被依赖的任务完成,只是通 ...

  5. IO模型 IO多路复用

    阻塞IO 用socket 一定会用到accept recv recvfrom这些方法正常情况下 accept recv recvfrom都是阻塞的 非阻塞IO 如果setblocking(False) ...

  6. linux 查看CPU内存 网络 流量 磁盘 IO

    使用vmstat命令来察看系统资源情况 在命令行方式下,如何查看CPU.内存的使用情况,网络流量和磁盘I/O? Q: 在命令行方式下,如何查看CPU.内存的使用情况,网络流量和磁盘I/O? A: 在命 ...

  7. IO模型——IO多路复用机制

    (1)I/O多路复用技术通过把多个I/O的阻塞复用到同一个select.poll或epoll的阻塞上,从而使得系统在单线程的情况下可以同时处理多个客户端请求.与传统的多线程/多进程模型比,I/O多路复 ...

  8. Python并发编程-IO模型-IO多路复用实现SocketServer

    Server.py import select import socket sk = socket.socket() sk.bind(('127.0.0.1',8080)) sk.setblockin ...

  9. Linux 网络编程的5种IO模型:信号驱动IO模型

    Linux 网络编程的5种IO模型:信号驱动IO模型 背景 上一讲 Linux 网络编程的5种IO模型:多路复用(select/poll/epoll) 我们讲解了多路复用等方面的知识,以及有关例程. ...

  10. [转载] Linux五种IO模型

      转载:http://blog.csdn.net/jay900323/article/details/18141217     Linux五种IO模型性能分析   目录(?)[-] 概念理解 Lin ...

随机推荐

  1. Windows编程之线程

    本笔记整理自:<Windows核心编程(第五版)> 目录 何为线程 线程的开始和结束 创建线程 终止线程 线程运行时的调度和线程优先级 挂起(暂停).恢复与睡眠 挂起 恢复 睡眠 线程切换 ...

  2. 如何写成高性能的代码(一):巧用Canvas绘制电子表格

    一.什么是Canvas Canvas是HTML5的标签,是HTML5的一种新特性,又称画板.顾名思义,我们可以将其理解为一块画布,支持在上面绘制矩形.圆形等图形或logo等. 需要注意的是,与其他标签 ...

  3. 2022CSP-J初赛游记

    2022年9月16日: 下午,在学校集训,刘洋让我看了一下时间,突然发现,距离初赛就剩2天了...... 晚上,辅导班的老师对我们进行最后的培训,做了2套有道小图灵模拟题,但是做的不理想,很慌. 20 ...

  4. 记录阿里云安全组设置遇到的奇葩问题--出口ip

    之前公司使用的路由器里使用的是PPPOE拨号的形式上网的,根据拨号后得到的ip地址,配置到阿里云的安全组里,具体来说是配置到22端口里,也就是说只有特定ip才能访问22端口,也即是说只允许公司网络远程 ...

  5. STM32F10x SPL V3.6.2 集成 FreeRTOS v202112

    STM32F10x SPL 集成 FreeRTOS 在整理 GCC Arm 工具链的Bluepill代码示例, 常用外设都差不多了, 接下来是 FreeRTOS, 网上查到的基本上都是基于旧版本的集成 ...

  6. set 学习笔记

    一.声明 1.头文件 \(include<set>//包括set和multiset两个容器\) 2.声明 \(set<int> s\) s自带一个维度 二.迭代器 对" ...

  7. Hbase之权限控制

    Hbase之权限控制 -- 只读权限 grant '{userName}','R','{namespaceName:tableName}' -- 写入权限 grant '{userName}','W' ...

  8. Pycharm安装使用

    目录 使用pycharm软件 配置调整 下载链接地址:https://www.jetbrains.com/pycharm/download/#section=windows 根据自己的系统需要安装对应 ...

  9. java实现双向链表的增删改查

    双向链表的增删改查 和单链表的操作很像:https://blog.csdn.net/weixin_43304253/article/details/119758276 基本结构 1.增加操作 1.链接 ...

  10. 齐博x1细节优化,自定义二、三、四维字段支持自定描述

    如下图所示,之前自定义字估中的二.三.四维字段,不支持自定义描述,导致用户输入的时候,不知道该输入什么信息内容.只有站长自己才知道. 现在支持自定义描述,及设置文本或数字.方便引导用户输入相应的信息内 ...