linux学习--第八天(多路复用IO)

多路复用IO

-阻塞IO与非阻塞IO

    -IO模型

        IO的本质时基于操作系统接口来控制底层的硬件之间数据传输,并且在操作系统中实现了多种不同的IO方式(模型)比较常见的有下列三种:

        1.阻塞型IO模型

        2.非阻塞型IO模型

        3.多路复用IO模型

-阻塞型IO

    概念:当进程发出IO请求后,阻塞进程(让进程进入睡眠状态),资源就绪后唤醒进程继续执行(一般默认的IO操作都是阻塞型IO)

    特点:会一直等待,直到数据就绪

de56232667c44c49ad08623095250920.png

-非阻塞型IO

        特点:程序不会等待用户输入,会立即返回

        当进程发出IO请求后,无论资源是否就绪都立即返回,相应的模型如下;

28faa3e916a746cfafb5278c43e1153a.png

    实现非阻塞型IO,需要设置O_NONBLOCK标志

    fcntl函数:通过命令字(cmd)来设置文件描述符

 

-多路复用IO

-多路复用IO简介

    本质:就是通过复用一个进程来处理多个IO请求

    基本思想:由内核来监控多个文件描述符是否可以进行I/O操作,如果就绪的文件描述符,将结果告知用户进程,则用户在进程相应的I/O操作

4528c771cbb547df8b3090156a9cc91c.png

-多路复用I/O方案

    目前在linux系统有三种多路复用I/O的方案

        1.select方案

        2.poll方案

        3.epoll方案

 

-select多路复用IO

-设计思想

   1.通过单进程创建一个文件描述符集合,将需要监控的文件描述符,添加到这个集合中

   2. 由内核负责监控文件描述符是否可以进行读写,一旦可以读写,则通知相应的进程进行相应的IO操作

75224749019b46719ca9fa9e9a79f994.png

    select函数:监控一组文件描述符,阻塞当前进程,由内核监测相应的文件描述符是否就绪,一旦文件描述符就绪,将就绪的文件描述符拷贝给进程,唤醒进程处理

   超时时间的说明:

        1.如果timeout之后,文件描述符集合中没有任何就绪的文件描述符,select函数就会返回0

        2.超时之后,timeout会被select函数修改,表示超时时间已经使用完

          如果想继续使用使用超时间,需要备份之前的struct timval

27d6113a0df647e7b2ed265d5c9a509e.png

 超时之后,,表示没有就绪的文件描述符,此外文件描述符集合被赋值为空

1d3f679b969c4ac3b669f89967a07487.png

因此,需要将之前的文件描述符集合进行备份

f0c845f0b78a41f6b60bc45b6ad46a54.png

 

-select底层原理分析

-文件描述符集合

    文件描述符集合的数组最终在储存时,使用了位图的方式来记录相应的文件描述符,具体原理如下:

        1.数组中没有直接存储文件描述符,而是使用某一位来表示该文件描述符是否需要监控

        2.需要监控的文件描述符需要转成数组的某一个元素的某一位,然后将对应的位设置为1

    例如:当 fd = 60 的成员需要监控,则需要将数组的第0个成员的第 [60] bit 设置为1,当 fd = 64时,则需要将数组的第1个成员的第[0] bit 设置为1

5b993ca0343e473ea5ab6f4941984003.png

    (从上面的文件描述符集合内管理可以分析,select最终只能存储1024个文件描述符)

select基本原理如下:

6e4e328b566f45a28392a380f04c6077.png

在 select() 函数中一共需要使用三个文件描述符集合,分别是:

        1.in: 需要进行读的文件描述符的集合

        2.out:需要进行写的文件描述符的集合

        3.exp:其他文件描述符集合

调用了select() 函数,内核做了如下事情:

        1.从用户空间将集合的文件描述符拷贝到内核空间

        2.循环遍历fd_set中所有的文件描述符,来检测是否有文件描述符可进行I/O操作

            1>如果文件描述符可进行I/O操作,则设置返回的文件描述符集合对应位为1(res_in,res_out,res_exp),跳出循环,直接返回。最终会赋值给in,out,exp 文件描述符集合

            2>如果没有文件描述符可进行IO操作,则继续循环检测,如果设置timeout,则在超时后返回,此时select()函数返回0

        select()函数减少了多进程/多线程的开销,但仍然有多缺点:

            1.每次调用select()函数都需要将fd集合拷问到内核空间,这个开销在fd很多时就越大

            2.每次都需要遍历所有的文件描述符集合,这个开销在fd很多时就越大

            3.支持的文件描述符只有2024

        整体流程

0a7436e0389549b98dc24b6734cae3b5.png

 

-poll多路复用IO

    基本原理

        1.在应用层是以struct polled数组的形式来进行管理文件描述符,在内核中基于链表对数组进行扩展

6482f353f9294975b989d70d5f585b42.png

    特点:

        1.poll将请求与就绪事件通过结构体进行分开

        2.select将请求与就绪文件描述符存储在同一个集合,导致每次都需要进行重新赋值才能进行下一次监控

        3.在内核中仍然使用的是轮询的方式,与select相同,当文件描述符越来越多时,则会影响效率

        POLLIN:普通数据可读

        POLLOUT:普通数据可写

    总体流程

b2f49e0a1d944909aa82a52b8a7fe801.png

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值