美文网首页
Unix系统下的I/O模型

Unix系统下的I/O模型

作者: EVANMORE | 来源:发表于2017-12-18 20:33 被阅读23次

    Unix系统下一共有5种I/O模型:

    • 阻塞式I/O;
    • 非阻塞式I/O;
    • I/O复用(select 和 poll);
    • 信号驱动的I/O(SIGIO);
    • 非同步式I/O(POSIX aio_函数);

    对于一个输入操作来说,通常就处于一下两个阶段:

    1. 等待数据准备好,等待网络上的数据到达;
    2. 从内核中拷贝数据到进程中,数据包接收到以后,首先是拷贝到内核空间的缓存中,然后再从内核中拷贝到应用程序的缓存中;

    1. 阻塞式I/O模型

    所有的sockets默认都是阻塞式的。
    以UDP为例,UDP协议下,数据是不是已经ready了判断条件很简单:整个数据块收到了;或者没收到。TCP协议的判断就相对要复杂一点,需要判断socket的低水位标志什么的。
    当使用系统调用recvfrom()函数去从一个配置成阻塞的socket来接收数据时,会一直阻塞等待直到数据可用。

    初始状态  ------阻塞------> 收到数据(结束)       
    

    这种模型下,如果没有数据收到,会一直阻塞在实际的用于I/O的系统调用recvfrom()

    2. 非阻塞式I/O模型

    如果sockets是非阻塞式的,recvfrom()函数会不停的进行系统调用,检查kernel中是否有数据ready

    • 如果没有数据ready,立即返回;
    • 如果内核中有数据ready,执行数据拷贝到用户空间,然后返回成功,
     检查 -> 检查 -> 检查 -> 检查 --阻塞进行数据拷贝> 完成接收
    

    3. I/O复用模型

    这种模型下,不同于之前的第一种模型,系统会阻塞在select或者poll这两个系统调用之一

    • 第一步,调用select()阻塞等待数据ready;一旦数据准备好了,返回成功;
    • 第二步,调用recvfrom()函数来实现从内核空间buffer到进程空间buffer的拷贝,接着返回OK,应用程序可以对接收到的数据进行处理。
      这种模型和第一种相比的好处是,可以同时处理多个socket;一旦有哪个socket有数据准备好了,就可以拷贝进用户空间继续处理。
      而阻塞式模型整个进程只能阻塞在某一个socket的数据I/O处理;如果有多个socket要进行数据I/O,则必须引入多线程。
    检查(poll/select) --阻塞等待--> 数据ready  --阻塞进行数据拷贝(recvfrom)--> 完成接收
    

    4. 信号驱动的I/O模型

    当内核中有数据ready时,内核会通过SIGNIO信号量来通知应用程序数据可用;接下来就可以通过recvfrom系统调用来完成数据拷贝。
    这是一种非阻塞式的I/O方式,用户程序可以继续运行。

    内核通知  --阻塞进行数据拷贝(recvfrom)--> 完成接收
    

    5. 非同步的I/O模型

    [REF]

    Unix Networking Programming

    相关文章

      网友评论

          本文标题:Unix系统下的I/O模型

          本文链接:https://www.haomeiwen.com/subject/ulfnixtx.html