前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >系列讲解网络 I/O , 从多进程多线程到异步 I/O 和多路复用

系列讲解网络 I/O , 从多进程多线程到异步 I/O 和多路复用

原创
作者头像
ge3m0r
发布2024-05-13 21:30:10
1220
发布2024-05-13 21:30:10

前言

网络 I/O 基本上是后端开发中不可避免的话题,只要涉及到网络基本上都会有这方面问题的处理。所以目前打算从整个 I/O 的实现阶段,从最开始多线程多进程的网络 I/O 模型, 到异步 I/O 和多路复用,当然还有线程池和 reactor 反应堆模型都进行,争取把网络 I/O 的大概一个框架讲清楚。当然本人也是为了将这方面的知识点捋清楚方便后来的面试,当然过程中肯定有详有略。但是争取讲清楚。

首先在说之前,我们需要明确的定义,我们通常说的 I/O 一般分为两个方面,一个是客户端的 I/O, 一个是服务端的 I/O ,后端更多打交道的是服务端的 I/O ,当然如果是做客户端软件也需要考虑客户端 I/O,当然客户端 I/O 模型总体来说较为简单,因为他面临的并发量一般来说是远远小于服务端的。

我们的应用程序 I/O 进行一个操作一般会经历这样的过程,应用端发起请求发起系统调用,进入内核,内核准备数据,数据到了之后将数据拷贝到应用,应用对数据进行处理。

I/O 的分类

目前 I/O 大致可以分为以下五种,阻塞 I/O, 非阻塞 I/O ,多路复用 I/O, 信号驱动 I/O, 异步 I/O。

当然前四个都从从处理流程上都可以归为同步 I/O。

阻塞 I/O

阻塞 I/O 比较简单,就是应用发起系统调用后,有数据就将数据返回,没有数据就等着,有数据后再返回。

阻塞 I/O
阻塞 I/O

我们在写一个服务器是的是一般是 socket() bind() listen() accept() recv() send(),其中accpet, send recv 都是阻塞 I/O。

上述一个监听线程处理所有请求,自然在速度会偏慢,而我们能想到最简单的改进方法,就是使用多进程或者多线程,一个程序负责监听和接受,但是每次连接后创建一个新的线程或者进程负责后续的对接。就好像一个负责人负责牵线,得到前期沟通的差不多了然后让另一个人负责后续的工作。

为什么主线程或者主进程可以接受多个请求,跟 TCP 三次握手不一样,这实际跟 accept 有关

代码语言:c
复制
int accept(int s, struct sockaddr *addr, socklen_t *addrlen);

这个函数是系统的一个 api 接口函数,他实际工作和我们自己看到代码逻辑其实不太一样,系统在 listen 接受到请求后会把数据添加到一个请求队列中,然后 accept 从请求队列中取出来请求,所以可以接收多个请求。

而多进程模型下通常会使用连接池和线程池,当然这只是减少了连接创建和销毁以及进程创建和销毁开销,本质上没有跳出多进程这个模型。

非阻塞 I/O

非阻塞 I/O 就是每次请求时候根据当前有没有数据直接返回一个状态,有就是有,没有就是没有,可以看到其中就是需要一个线程循环请求,直到有结果为止。

非阻塞 I/O
非阻塞 I/O

通过上述图片就会发现每次系统调用都会返回目前数据状态,只有数据同步之后然后就会阻塞 I/O 拷贝数据。

多路复用

多路复用也就是经常说的 select poll epoll ,他的想法较为简单,既然有很多连接,那我一个线程专门去管理很多这样的 I/O ,并且其中那个有事情发生后,我可以立刻进行响应,所以这个也叫事件驱动 I/O。

select I/O 多路复用
select I/O 多路复用

简单来说只阻塞 select 一个进程,但是造福了所有其他 socket 。select 将所有的 socket 加入 select ,等到 select 中某个 socket 就绪之后,然后通知进程,然后进行数据读取。

epoll 本质上都是一样的,只不过 socket 都存储在红黑树中,而且会对就绪的数据存储在链表中,方便读取。

异步 I/O

异步 I/O 是数据将发起系统调用后立刻去做其他事情,等到数据就绪后,内核发送一个 singnal 给用户态直接将数据返回到应用程序,用来数据后续作用。

异步 I/O
异步 I/O

从上边可以直到异步 I/O 不会阻塞线程,而其他线程,通过系统调用读取数据过程中都会阻塞 I/O。

信号驱动 I/O

异步 I/O 首先会注册一个信号函数,然后数据就绪后通知进行进行数据读取。

信号驱动 I/O
信号驱动 I/O

至此,五种 I/O 都已经介绍完毕,那么明天上代码。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • I/O 的分类
    • 阻塞 I/O
      • 非阻塞 I/O
        • 多路复用
          • 异步 I/O
            • 信号驱动 I/O
            相关产品与服务
            数据保险箱
            数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档