UNIX的网络I/O模型

UNIX的网络I/O模型:linux

    概念:
        1)linux内核对一个文件的读写操做会调用内核提供的系统命令,返回一个文件描述符(file discriptor,简称fd)。
            描述符就是一个数字,它指向内核中的一个结构体,这个结构体包含了文件路径等信息。 eg:对socket的读写会返回一个描述符 socketfd
        2)一次⽹络I/O的读操做会包含下面这两个阶段:1)等待数据准备就绪 2)数据从内核复制到用户空间(即用户进程)。缓存


    1)阻塞I/O模型:blocking I/O
        概念:用户进程从阻塞的socket中读取数据时,只有当数据包到达该socket的接收缓存区且数据被复制到进程空间的缓存区中 或 发生错误时 才返回,在此期间进程会一直阻塞等待。服务器

        说明:默认状况下,全部的文件操做都是阻塞的。
        缺点:客户端的并发访问量比较高时,服务端须要建立大量的线程来响应请求,当线程的数量膨胀后,系统的性能会急剧降低甚至宕机。网络

        伪异步I/O模型:
            概念:为了解决阻塞I/O模型中须要为每个请求都建立一个线程的问题,服务端可使用线程池来实现一个伪异步I/O模型。
            伪异步I/O模型可能致使的级联故障:某台服务器故障致使响应缓慢 -> 线程读取故障服务节点的响应 -> 全部线程被故障节点阻塞,后续IO消息都在队列中 -> 队列积满 -> 新的客户端请求被拒绝,服务器无响应并发

    2)非阻塞I/O模型:nonblocking I/O
        概念:用户进程从非阻塞的socket中读取数据时,若该套接字的接收缓存区中没有数据,则内核会直接返回一个错误。异步

        说明:通常当socket设为非阻塞状态时,用户进程会轮询内核(eg:循环调用recvfrom函数),直到内核有数据返回为止,所以会致使大量cpu资源被占用。socket


    3)I/O复用模型:I/O multiplexing
        概念:将多个待监听的fd注册到多路复用器(selector)中,注册的时候须要指定该fd上待监听的事件,selector会一直监听注册的fd,当fd上有事件发生时,selector会作出相应的处理。函数

        说明:
            与阻塞I/O模型相比,I/O复用模型是阻塞在select调用(或poll调用、或epoll调用)上,而不是阻塞在真正的I/O操做上。注意:阻塞是针对发起方而言的。
            获取fd的状态:内核把fd的信息通知给用户空间。
            水平触发:若就绪的fd未被用户进程处理,则该fd在下一次查询时依旧会返回。
            边缘触发:不管就绪的fd是否被用户进程处理,该fd在下一次查询时将再也不返回。性能

        优势:
            客户端发起的链接操做是异步的,故单线程能够同时处理多个客户端的IO请求。系统不须要为每一个客户端请求都建立一个线程,这样大大下降了系统的开销,
        缺点:操作系统


        select调用:
            概念:多路复用器(selector)由select函数实现。

            监听机制:
                轮询注册的fd,并根据fd的状态作相应的处理:
                    读就绪状态             ->    读数据 并 删除该读就绪事件
                    写就绪状态             ->    写数据 并 删除该写就绪事件
                    接收(accept)就绪状态     ->    注册新的读就绪事件 并 删除该接收就绪事件
                    ...
                获取fd的状态:内核把全部监听的fd的信息总体复制到用户空间。

            触发方式:水平触发。

            优势:与非阻塞式I/O模式相比,select调用不须要客户端不断地发出请求。
            缺点:
                单个进程能够打开的fd数量有限,默认1024个,若是要修改这个默认值,须要从新编译内核。
                每次select调用都会线性地扫描全部监听的fd(即:不管fd是否就绪,select都会去检查它的状态),当监听的fd数量比较多时,I/O效率呈线性降低。

        poll调用:
            概念:多路复用器(selector)由poll函数实现。

            监听机制:同select调用。

            触发方式:水平触发。

            优势:
                单个进程能够打开的fd数量不受限制。
            缺点:
                线性地扫描全部监听的fd,当监听的fd数量比较多时,I/O效率呈线性降低。

        epoll调用:
            概念:selector由一系列epoll_函数实现。

            监听机制:
                当fd就绪时,fd会当即回调rollback函数。而那些没有就绪的fd则不会回调rollback函数。
                获取fd的状态:使用内存映射,不须要把fd的信息从内核复制到用户空间。

            触发方式:默认是水平触发,支持边缘触发。

            优势:
                单个进程能够打开的fd数量不受限制。(仅受限于操做系统的最大文件句柄数,1g内存的最大文件句柄数为10w左右)
                因为epoll采用的是回调函数的方式,而不是线性扫描的方式,故I/O效率不会随着fd数量的增长而线性降低。
                使用内存映射,避免了内存复制的开销,加速了内核与用户空间的消息传递。
            缺点:
                在链接数少而且链接都十分活跃的状况下,epoll的性能可能比select和poll的性能差,毕竟epoll的通知机制须要不少函数回调。


    4)信号驱动式I/O模型:SIGIO
        开启套接字信号驱动IO功能,并经过sigaction系统调用,执行一个信号处理函数,当数据报准备好时,内核就为该进程产生一个SIGIO信号,用户进程收到这个信号后,就能够开始进行I/O操做了。
        该系统调用会当即返回,在等待数据报到达期间,用户进程不会被阻塞。
        
        说明:信号驱动式I/O模型使用的场景比较少。


    5)异步I/O模型:POSIX定义的异步IO函数
        
        调用异步IO函数,让内核在整个I/O操做(包括将数据从内核复制到用户本身的缓冲区)完成后通知用户进程。
        该系统调用会当即返回,在等待I/O操做期间,用户进程不被阻塞。

        说明:同步/异步是针对执行方而言的。

相关文章
相关标签/搜索