五种I/O模型的介绍与区分

有时我们在进行系统调用时为什么有的会立即返回,有的会阻塞在那里,而且系统调用的形参都不一样,其实就是因为在设计时采用了不同的I/O机制

阻塞式I/O:

    一般我们使用的系统调用接口都是阻塞式的。 此种模式,如果在只有一个主线程的情况下,线程就会阻塞在那里。导致我们什么其他的事都干不了,只有在数据报到达且被复制到应用进程的缓冲区中或者发生错误,这个系统调用才会返回。

    系统调用接口举例:recvfrom

       

非阻塞式I/O: 

    这种模式下系统调用后会立即返回,比如说是一个状态, EWOULDBLOCK, 表示数据还没有准备好。所以就要用户写一个循环函数不停的进行系统调用并对状态判断,然后根据状态来决定怎么做。和阻塞式IO不同的地方是,非阻塞式可以做一些事情,但还是会有束缚。

    系统调用接口举例: recvfrom

I/O复用的实现机制: 

       让select(或者poll)函数作为替身阻塞的等待描述符就绪, 当select返回套接字可读这一条件时,我们调用recvfrom把所读数据复制到应用进程缓冲区(注意此时select返回时,还是要通过recvfrom函数去进行系统调用,其过程就是将内核空间的内容复制到进程空间,此点会和异步IO做区分)。select 在只有一个文件描述符的情况下与非阻塞的相比并没有优势, select的优势在于可以等待多个描述符。


信号驱动式I/O

       首先开启信号驱动式I/O功能, 并通过sigaction系统调用安装一个信号处理函数。该系统调用将立即返回, 我们的进程继续工 作(没有被阻塞,这是其区别与I/O复用的关键)当数据准备好时, 内核就为该进程准备一个SIGIO信号。我们既可以在信号处理函数中调用recvfrom读取数据报,并通知主循环去处理数据报,也可以立即通知主循环,让它读取数据。

       优势在于数据报到达期间进程不被阻塞。主循环可以继续执行。

异步I/O:  

        我们调用aio_read函数,给内核传递描述符、缓冲区指针、缓冲区大小和文件偏移、并高速内核整个操作完成时该怎么通知我们。 该信号直到数据已复制到应用进程缓冲区才产生,这一点不同于信号驱动式I/O


小结:理解的关键在于要懂应用进程空间和内核空间,内核空间的函数可以操作进程空间(在异步IO中,内核函数直接将内容拷贝到进程空间的缓冲区中) 但进程空间必须通过系统调用才可以读取内核空间的内容。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值