Linux高阶IO 1

1 篇文章 0 订阅
1 篇文章 0 订阅

高阶IO

五种IO模型

1.阻塞IO
2.非阻塞IO
3.信号驱动IO
4.多路转接IO
5.异步IO

阻塞IO与非阻塞IO
阻塞IO非阻塞IO
为了完成功能发起调用,但是如果当前不具备完成条件,则等待。为了完成功能发起调用,但是如果当前不具备完成条件,则立即报错返回
  • 阻塞IO与非阻塞IO之间最大的区别在于当不具备完成条件时,是否立即返回
同步与异步
同步异步
为了完成功能发起调用但是如果当前不具备完成条件,则等待,直到完成。为了完成功能发起调用,但是如果当前不具备完成条件,则立即返回(将完成功能的操作交给操作系统,当操作系统完成操作之后会以一些其他的方式(信号通知等)告诉我们功能完成)
  • 同步与异步最大的区别:当不具备完成功能的条件下,是否会阻塞完成。

多路转接(多路复用模型)
  • 让别人替我们监控等待的整个过程,看现在有哪一个就绪好了,直到完成相应的操作。
    使用多路转接模型替用户完成监控多个描述符的等待过程,如果哪一个描述符就绪,则完成监控过程返回,并通知我们有描述符就绪,接下来用户直接读取数据即可。
信号驱动IO

非阻塞IO的实现

这里需要使用一个函数:fcntl()

使用的头文件:

       #include <unistd.h>
       #include <fcntl.h>

函数结构:

       int fcntl(int fd, int cmd, ... /* arg */ );
       //fd : 文件描述符
       //cmd: 
       //       F_GETFL     获取属性状态 (通过返回值返回当前属性)
       //       F_SETFL     设置属性状态 (替换原有属性为当前arg属性)
       // arg:   要设置的属性信息
       //       O_NONBLOCK  设置描述符为非阻塞
       //  返回值:F_GETFL:当前属性  
       //               F_SETFL:成功:0 失败:-1
多路转接模型的实现

使用函数:select()
使用这个函数需要使用的头文件

      #include <sys/select.h>
      #include <unistd.h>   

函数的结构:

       int select(int nfds, fd_set *readfds, fd_set *writefds,
                     fd_set *exceptfds, struct timeval *timeout);
     //  nfds:   最大的描述符+1
     //  readfds:   可读事件的监控集合
     //  writefds:  可写事件的监控集合
     //  exceptfds: 异常事件的监控集合
     //  timeout:   超时等待事件
     //          NULL    没有描述符就绪则永久阻塞等待
     //          struct timeval
     //              tv_sec      秒
     //              tv_usec     微秒
     //  返回值:<0:出错     ==0:等待超时了     >0  就绪的描述符个数
    
    
     //还使用到了 
     //int  FD_ISSET(int fd, fd_set *set)
     //判断描述符是否存在于集合中
多路转接模型实现的过程描述

多路转接的功能:

  • 对大量描述符进行事件阻塞监控,当描述符状态发生改变时,则返回

select:

  • 功能:同时对大量描述符进行事件阻塞监控(可读 可写 异常),状态改变时返回
    select:创建的三个描述符集合,分别对可读事件,可写事件,异常事件进行监控。

集合:

  • 集合实际上就是一个位图,添加描述符实际上就是修改位图对应比特位,位图大小取决于FD_SETSIZE。向集合中添加描述符,对描述符关注什么样的状态就添加到对应的描述符集合中。
    然后将集合中的数据拷贝到内核中,进行阻塞监控(间隔事件,轮询遍历,判断是否有描述福就绪)

就绪:

  • 描述符对应缓冲区中数据大小/空闲空间大小是否大于低水位标记
    若是编译没有描述符就绪,则继续休眠等待/判断是否超时,超时则返回0。
    若是有描述就绪,将集合中没有就绪的描述符全部从集合中移除(集合中保留的都是就绪描述符)
    因为对集合进行了修改,因此需要每次清空集合,向集合重新添加描述符)
    遍历从0~maxfd的描述符,判断是否在集合中(目的:为了找到具体是哪一个描述符就绪)
    对就绪描述符进行相应的操作
select优缺点
缺点优点
能够监控的描述符有最大上限(因为位图最大取决于FD_SETSZIE)跨平台
因为select判断集合中描述符就绪后会修改集合内容,因此需要每次重新添加描述符(编程麻烦,随着描述符的增多,效率会随之降低)超时时间的控制比较精细
因为select不会告诉我们具体哪一个描述符准备就绪,因此需要用户进行遍历判断(编程麻烦,随着描述符的增多,效率会随之降低)
因为select每次都需要将集合数据拷贝到内核,并且在内核是轮训遍历实现监控,因此(性能随着描述符的增多而降低)
poll模型原理
缺点相较于select优点
因为select判断集合中描述符就绪后会修改集合内容,因此需要每次重新添加描述符(编程麻烦,随着描述符的增多,效率会随之降低)描述符无上限
因为select不会告诉我们具体哪一个描述符准备就绪,因此需要用户进行遍历判断(编程麻烦,随着描述符的增多,效率会随之降低)监控集合只有一个,每个节点可以关注不同事件,不用针对不同的事件进行多次遍历
因为select每次都需要将集合数据拷贝到内核,并且在内核是轮训遍历实现监控,因此(性能随着描述符的增多而降低)

后续:
高阶IO 2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值