• Unix网络编程笔记IO模型


    本文内容来自《UNIX网络编程 卷1:套接字联网API》

    I/O 模型

    unix系统共有5种I/O模型

    1. 阻塞式IO

    2. 非阻塞式IO

    3. IO多路复用

    4. 信号驱动式IO

    5. 异步IO

    一个输入操作通常包括两个不同的阶段:

    1. 等待数据准备好

    2. 从内核向进程复制数据

    对应一个套接字上的操作,第一步通常涉及数据从网络到达,当所有数据到达时,它被复制到内核的某个缓冲区。第二步就是从内核缓冲区复制到用户进程的缓冲区。

    一、阻塞式IO

    最流行IO是阻塞式IO,如下图所示,用户进程调用recvfrom,recvfrom系统调用直到数据复制到用户进程缓冲区或发生错误才返回。整段时间用户进程是被阻塞的。

    二、非阻塞式IO

    进程把一个套接字设置成非阻塞是通知内核:当所有请求的IO操作非得把本进程投入睡眠才能完成时,不要把本进程投入睡眠。而是返回一个错误。

    前三次调用recvfrom都没有返回,因此内核直接返回一个EWOULDBLOCK错误,第四次调用recvfrom时数据已经准备好,然后被复制到应用进程缓冲区。于是recvfrom成功返回。

    当一个应用进程对非阻塞描述符循环调用recvfrom时,我们称之为轮询(polling),应用进程持续轮询内核以查看某个操作是否就绪,这样做往往耗费大量CPU时间。这种模型偶尔会用到。

    三、IO多路复用

    有了IO多路复用(IO multiplexing),我们就可以调用select或poll,阻塞在这两个系统调用中的某一个之上,而不是阻塞在真正的IO系统调用上。

    我们阻塞在select,等待数据报套接字变成可读,当select返回套接字可读这一条件是,我们调用recvfrom把数据复制到应用进程缓冲区。

    事实上由于使用select复制数据需要两个系统调用而不是之前的一个,似乎还有劣势,其实select的优势在于,我们可以用select在等待多个描述符就绪。

    四、信号驱动IO模型

    我们也可以用信号,让内核在描述符就绪时发生SIGIO通知我们,这就是信号驱动式IO,如下图

    我们首先开启套接字的信号驱动式IO功能,并通过sigaction系统调用安装一个信号处理函数,该系统调用立即返回。进程继续工作。当数据报就绪时,内核为该进程产生一个SIGIO信号,进程可以通过在信号处理函数中调用recvfrom读取数据。也可以通知主循环让他读取数据报。

    无论如何处理SIGIO信号,这种模型的优势在于等待数据报到达期间不被阻塞,主循环可以继续执行。

    五、异步IO模型

    异步IO由POSIX规范定义,一般来说的工作机制是:告诉内核启动某个操作(包括数据从内核复制到进程缓冲区),并让内核在整个操作完成后通知我们。

    这一模型与信号驱动IO模型的区别在于,信号驱动IO是内核通知我们何时可以启动一个IO,而异步IO通知我们IO操作何时完成。

    我们调用aio_read函数,给内核传递描述符、缓冲区指针、缓冲区大小(同read)和文件偏移(同lseek),并告诉内核在整个操作完成后通知我们。

    该系统调用立即返回,而且在等待IO完成期间,进程不会被阻塞。

    该信号直到数据被复制到应用进程缓冲区才产生,这一点与信号驱动IO不同。

    各种IO模型的比较

    前四种模型的主要区别在第一阶段,他们的第二阶段是一样的。

    异步IO模型两个阶段都是异步非阻塞的。因此与前面四个模型不同。

    POSIX把下面两个定义为:

    同步IO操作:导致请求进程阻塞,指定IO操作完成

    异步IO操作:不导致请求进程阻塞

    从上面的定义来看,前面四种模型都是同步IO模型,因为recvfrom是阻塞的,只有最后一种是异步IO模型

     

  • 相关阅读:
    DTS和AC3的区别
    bind出现 file does not end with newline错误
    删除桌面菜单多余项
    you have requested a nonexistent service "grid"
    php 常用函数
    Jquery
    Twig 的Filters学习
    Twig 的 tags学习(中文) 之三 完结
    PHP 正则表达式
    SQL处理字符串
  • 原文地址:https://www.cnblogs.com/wangbin2188/p/16194557.html
Copyright © 2020-2023  润新知