什么是I/O复用?

What we need is the capability to tell the kernel that we want to be notified if one or more I/O conditions are ready (i.e., input is ready to be read, or the descriptor is capable of taking more output). This capability is called I/O multiplexing and is provided by the select and poll functions. ——来自《Unix网络编程》第三卷

在很多情况下,使用select或是poll,可以把事件的响应交给底层操作系统来管理,当有I/O事件发生时,操作系统会通知我们。

何时使用I/O复用:

1、When a client is handling multiple descriptors (normally interactive input and a network socket), I/O multiplexing should be used. This is the scenario we described previously.

2、It is possible, but rare, for a client to handle multiple sockets at the same time. We will show an example of this using select in Section 16.5 in the context of a Web client.

3、If a TCP server handles both a listening socket and its connected sockets, I/O multiplexing is normally used.

4、If a server handles both TCP and UDP, I/O multiplexing is normally used.

5、If a server handles multiple services and perhaps multiple protocols, I/O multiplexing is normally used.

——来自《Unix网络编程》第三卷

I/O模型

对于read而言,一般都会涉及到两个过程:

1. Waiting for the data to be ready 
2. Copying the data from the kernel to the process

接下来的讨论,会根据这两阶段的操作进行描述。

I/O一共有5大模型:

1、阻塞I/O

应用进程产生一个system call ,如果内核没有数据准备好,则会一直wait,处于阻塞,当内核数据准备好之后,将会把数据从内核再拷贝到应用进程,这一copy过程也处于阻塞状态。

2、非阻塞I/O

之所以称作为非阻塞I/O,就意味着当应用进程产生一个system call的时候,不管内核的数据是否准备好,都会立即返回。而后,再一次发起call,这是一个轮询的过程。当内核数据准备好之后,便可以正常进行响应。这一过程是非阻塞的。而当数据从内核copy到应用进程的过程,仍然是阻塞,应为要保证数据完整与一致。

3、I/O复用

使用I/O复用,一个或多个 system call 阻塞于select 或是 poll,而不是阻塞与真正的调用。当内核有数据准备好的时候,会通知select或是poll,接下来,会发起真正的system call,也就是图片中的recvfrom。之后,便会正常copy数据到应用进程。值得注意的是,I/O复用产生了两次system call,一次select(poll),一次recvfrom。因此,如果进程只是处理单一描述字(descriptor)的话,使用I/O复用不但不会有好的效果,而且还会有额外的系统开销,所以,I/O复用一般都用于处理多个描述字(descriptors)的情况下。

4、信号驱动I/O

我们可以使用信号驱动I/O,当有描述字准备好后,内核会产生信号来通知应用进程。信号驱动模型不同于上述三种,对于应用进程而言,它在等待接受数据过程中,处于被通知状态。这一过程,相当于一个异步操作。但是,对于内核copy数据到应用进程这一过程,应用进程仍然处于阻塞的状态。

5、异步I/O

信号驱动I/O模型中,在等待内核数据准备阶段中,是一个异步的过程,而数据copy阶段则是阻塞的,也就是同步的。但是对于异步I/O模型而言,这两个阶段都是异步的。也就说,当引用进程产生一个aio_read后,它会继续执行其他操作,整个过程不会产生任何阻塞。

“We call aio_read (the POSIX asynchronous I/O functions begin with aio_ or lio_) and pass the kernel the descriptor, buffer pointer, buffer size (the same three arguments for read), file offset (similar to lseek), and how to notify us when the entire operation is complete.” ——来自《Unix网络编程》第三卷

5个I/O模型的比较总结:

总结:

在本文中,主要介绍了什么是I/O复用,I/O复用的应用场景,已经5大I/O模型的介绍。 在下一篇博文中,会重点介绍Unix环境下select和poll的原理、实际应用以及代码实现。

unix下网络编程之I/O复用(一)的更多相关文章

  1. unix下网络编程之I/O复用(三)

    poll函数 在上文unix下网络编程之I/O复用(二)中已经介绍了select函数的相关使用,本文将介绍另一个常用的I/O复用函数poll.poll提供的功能与select类似,不过在处理流设备时, ...

  2. unix下网络编程之I/O复用(五)

    前言 本章节是用基本的Linux/Unix基本函数加上select调用编写一个完整的服务器和客户端例子,可在Linux(ubuntu)和Unix(freebsd)上运行,客户端和服务端的功能如下: 客 ...

  3. unix下网络编程之I/O复用(二)

    select函数 该函数允许进程指示内核等待多个事件中的任何一个发生,并仅在有一个或是多个事件发生或经历一段指定的时间后才唤醒它.我们调用select告知内核对哪些描述字(就读.写或异常条件)感兴趣以 ...

  4. unix下网络编程之I/O复用(四)

    首先需要了解的是select函数: select函数 #include<sys/select.h> #include<sys/time.h> int select (int m ...

  5. TCP/IP网络编程之I/O复用

    基于I/O复用的服务端 在前面章节的学习中,我们看到了当有新的客户端请求时,服务端进程会创建一个子进程,用于处理和客户端的连接和处理客户端的请求.这是一种并发处理客户端请求的方案,但并不是一个很好的方 ...

  6. python3网络编程之socketserver

    本节主要是讲解python3网络编程之socketserver,在上一节中我们讲到了socket.由于socket无法支持多用户和多并发,于是就有了socket server. socket serv ...

  7. GO语言的进阶之路-网络编程之socket

    GO语言的进阶之路-网络编程之socket 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是socket; 在说socket之前,我们要对两个概念要有所了解,就是IP和端口 ...

  8. 网络编程之socket

    网络编程之socket socket:在网络编程中的一个基本组件,也称套接字. 一个套接字就是socket模块中的socket类的一个实例. 套接字包括两个: 服务器套接字和客户机套接字 套接字的实例 ...

  9. java网络编程之TCP通讯

    java中的网络编程之TCP协议的详细介绍,以及如何使用,同时我在下面举2例说明如何搭配IO流进行操作, /* *TCP *建立连接,形成传输数据的通道: *在连接中进行大数据量传输: *通过三次握手 ...

随机推荐

  1. 结合canvas做雨滴特效

    雨滴特效 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <titl ...

  2. arguments解析

    js中并没有函数重载的概念,但函数的arguments参数能帮助我们模拟重载. arguments并不是真正的数组,但拥有length(参数数目),且能通过数组下标的方式进行访问,例如argument ...

  3. 我的python开发目录模块连接

    一.python语言 二.HTML 三.css 四.javascript 五.DOM 六.jquery 七.AJAX 八.WEB前端插件 九.自定义WEB框架 十.WEB框架之tornado 十一.M ...

  4. INSPIRED启示录 读书笔记 - 第13章 产品原则

    确定什么最重要 产品原则是对团队信仰和价值观的总结,用来指导产品团队作出正确的决策和取舍.它体现了产品团队的目标和愿景,是产品战略的重要组成部分.从形式上看,它是一系列明确的.体现团队特色的产品价值准 ...

  5. kubernetes liveness readiness

    Liveness Probe(存活探针):用于判断容器是否存货(running状态),如果LivenessProbe探测到容器不健康,则kubelet将杀掉该容器,并根据容器的重启策略做相应的处理.如 ...

  6. mongoDB中批量修改字段

    // 为每一个文章文档新增一个image_count字段,用于记录此文章包含的图片个数 db['test.articles'].find({'title':'wfc test'}).forEach( ...

  7. awk之腾迅面试题1

    1.题目如下: 3 5 6 72 3 1 04 5 6 92 3 4 42 2 1 04 5 0 9假如把2列和3列的值作为新的第5列,第5列的平均值为avg5,求第5列中大于avg5的行数.  aw ...

  8. docker安装---CentOS_7

    操作系统要求 要安装Docker,您需要64位版本的CentOS 7.步骤:   卸载旧版本 Docker的旧版本被称为docker或docker-engine . 如果这些已安装,请卸载它们以及关联 ...

  9. WPF的Presenter(ContentPresenter)

    WPF的Presenter(ContentPresenter) 2010-12-20 14:34 by Clingingboy, 10619 阅读, 3 评论, 收藏, 编辑 这是2年前写了一篇文章 ...

  10. zoj2314 无源汇上下界可行流

    题意:看是否有无源汇上下界可行流,如果有输出流量 题解:对于每一条边u->v,上界high,下界low,来说,我们可以建立每条边流量为high-low,那么这样得到的流量可能会不守恒(流入量!= ...