美文网首页
unix 下5种io模型

unix 下5种io模型

作者: juteman | 来源:发表于2018-03-02 15:35 被阅读18次

文章从我的个人博客备份而来
unix下有5种可用的io模型,它们分别是:

  • 阻塞io
  • 非阻塞io
  • io复用
  • 信号式驱动io
  • 以及异步io

阻塞式io模型

一般来说,我们平时编程使用的最多的,就是阻塞式io模型。
举个例子,比如说我们有一个函数

struct hostent *gethostbyname(const char *name);

这个时候我们调用这个函数

gethostbyname("www.google.cn")

进程会一直阻塞,直到调用完成,或者调用失败。


阻塞式io.jpg

非阻塞式io

在类unix操作系统下,我们有:

fcntl(fd, F_SETFL, O_NONBLOCK);

这里的fd可以是文件描述符,也可以是套接字描述符。
假设我们调用了

recv(fd, buf, sizeof(buf), 0)

如果是服务端接收客户端的信息,假如客户端的数据没有准备好,服务端并不会被阻塞,而是会发起轮询。

轮询.jpg

但是假如我们有多个客户端,都设为非阻塞式,那么我们会对多个客户端都发起轮询。这样非常的消耗资源。在某些特定的情况,我们会使用非阻塞式的模型

io复用模型

这里使用常见的select()来介绍:

复用io.jpg

进程阻塞于select()调用,当条件准备好的时候,我们调用recv().
和阻塞式io比起来,这好像没什么区别,还多了一次select()调用。对于单个套接字来说,确实是这样。但是对于多个套接字来说效率会大大的提高。
假设我们有fd[0], fd[1], fd[2], .... fd[n] (n < 1024)
如果我们采用阻塞式io的话,这时我们遍历 fd数组,而在这个数组中fd[3]是准备好的,而fd[0], fd[1], fd[2]都没有准备好。我们会一直阻塞到直到fd[0],fd[1],fd[2]都准备好才会使用recv接收fd[3]的数据。
假如我们使用select(),遍历过fd数组以后确认fd[3]是准备好的则会先执行fd[3]。

下面是一段复用的示例程序

fd_set readset;
int i, n;
char buf[1024];

while (i_still_want_to_read()) {
    int maxfd = -1;
    FD_ZERO(&readset);

    for (i=0; i < n_sockets; ++i) {
         if (fd[i]>maxfd) maxfd = fd[i];
         FD_SET(fd[i], &readset);
    }

    select(maxfd+1, &readset, NULL, NULL, NULL);

    for (i=0; i < n_sockets; ++i) {
        if (FD_ISSET(fd[i], &readset)) {
            n = recv(fd[i], buf, sizeof(buf), 0);
            if (n == 0) {
                handle_close(fd[i]);
            } else if (n < 0) {
                if (errno == EAGAIN)
                else
                     handle_error(fd[i], errno);
             } else {
                handle_input(fd[i], buf, n);
             }
        }
    }
}

但是select有许多缺点,比如说它每次扫描都是线性扫描,当描述符变得很多以后,他的效率会非常的低。而且单个进程打开的fd数量是有限制的,默认是1024.而另一个unix提供的poll()函数同样也会随着套接字的增加效率降低。
在Linux2.6内核以后提供了epoll(),而freebsd也提供了kqueue。相比起poll(),select(),他们更加的优秀。

信号式驱动

假设我们还是服务器接收客户端的数据,信号式驱动是客户端先发送一个信号表示数据已经准备好,可以发送。这种方法的优势在于等待期间我们的进程不会被阻塞。

异步io模型

还是我们调用一个函数,异步io在执行时进程并不会被阻塞,而在执行完成之时,会传递一个信号来告知执行完成。

最后用一张图来看看5中io的区别

5种io模型.jpg

相关文章

  • Unix下5种IO模型

    目录一:Unix下5种IO模型二:同步I/O和异步I/O 一:Unix下5种IO模型 阻塞式IO 非阻塞式IO I...

  • 【Netty开发指南】搭稳Netty开发的地基

    Linux网络编程5种IO模型 根据UNIX网络编程对于IO模型的分类,UNIX提供了5种IO模型,分别是 阻塞I...

  • linux select/epoll

    一、Unix/Linux网络IO模型在经典的Unix网络编程中,总结出了5种不同的网络IO模型,分别是阻塞式IO,...

  • Unix IO模型

    1.同步,异步,阻塞,非阻塞的概念:一般来说,一个输入操作包含两个阶段:(1)等待数据准备好(2)将数据从内核拷贝...

  • unix 下5种io模型

    文章从我的个人博客备份而来unix下有5种可用的io模型,它们分别是: 阻塞io 非阻塞io io复用 信号式驱动...

  • 2020-02-19 阻塞IO和非阻塞IO

    unix系统下常见的五种IO模型 阻塞式 非阻塞式 IO复用(select,poll) 信号驱动(SIGIO) 异...

  • IO模型

    描述 本文摘自UNIX网络编程卷1:套接字联网API,描述了UNIX中五种IO模型。阻塞IO、非阻塞IO、IO复用...

  • 彻底搞懂Java的网络IO

    IO是Input/Output的缩写。Unix网络编程中有五种IO模型: blocking IO(阻塞IO) no...

  • UNIX下的5种IO模型

    套接字的IO操作,如recvfrom,分为两个阶段: (1)等待内核中的接收缓冲区中有数据可读。 (2)将接收缓冲...

  • 四、高性能IO模型浅析

    按照《Unix网络编程》的划分,IO模型可以分为:阻塞IO、非阻塞IO、IO复用、信号驱动IO和异步IO;按照PO...

网友评论

      本文标题:unix 下5种io模型

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