I/O模型详细解析
内核空间和用户空间:
由于操作系统都包括内核空间和用户空间(或者说内核态和用户态),内核空间主要存放的是内核代码和数据,是供系统进程使用的空间。而用户空间主要存放的是用户代码和数据,是供用户进程使用的空间。目前Linux系统简化了分段机制,使得虚拟地址与线性地址总是保持一致,因此,Linux系统的虚拟地址也是0-4G。Linux系统将这4G空间分为了两个部分:将最高的1G空间(从虚拟地址0xC0000000到0xFFFFFFFF)供内核使用,即为“内核空间”,而将较低的3G空间(从虚拟地址 0x00000000到0xBFFFFFFF)供用户进程使用,即为“用户空间”。同时由于每个用户进程都可以通过系统调用进入到内核空间,因此Linux的内核空间可以认为是被所有用户进程所共享的,因此对于一个具体用户进程来说,它可以访问的虚拟内存地址就是0-4G。另外Linux系统分为了四种特权级:0~3,主要是用来保护资源。0级特权最高,而3级则为最低,系统进程主要运行在0级,用户进程主要运行在3级。
一般来说,IO操作都分为两个阶段,就拿套接口的输入操作来说,它的两个阶段主要是:
1)等待网络数据到来,当分组到来时,将其拷贝到内核空间的临时缓冲区中
2)将内核空间临时缓冲区中的数据拷贝到用户空间缓冲区中
服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种:
(1)同步阻塞IO(Blocking IO):即传统的IO模型。
(2)同步非阻塞IO(Non-blocking IO):默认创建的socket都是阻塞的,非阻塞IO要求socket被设置为NONBLOCK。注意这里所说的NIO并非Java的NIO(New IO)库。
(3)IO多路复用(IO Multiplexing):即经典的Reactor设计模式,有时也称为异步阻塞IO,Java中的Selector和Linux中的epoll都是这种模型。
(4)异步IO(Asynchronous IO):即经典的Proactor设计模式,也称为异步非阻塞IO。
同步和异步的概念描述的是用户线程与内核的交互方式:同步是指用户线程发起IO请求后需要等待或者轮询内核IO操作完成后才能继续执行;而异步是指用户线程发起IO请求后仍继续执行,当内核IO操作完成后会通知用户线程,或者调用用户线程注册的回调函数。
阻塞和非阻塞的概念描述的是用户线程调用内核IO操作的方式:阻塞是指IO操作需要彻底完成后才返回到用户空间;而非阻塞是指IO操作被调用后立即返回给用户一个状态值,无需等到IO操作彻底完成。
对于一个network IO (这里我们以read举例),它会涉及到两个系统对象,一个是调用这个IO的process (or thread),另一个就是系统内核(kernel)。当一个read操作发生时,它会经历两个阶段:
1 等待数据准备 (Waiting for the data to be ready)
2 将数据从内核拷贝到进程中 (Copying the data from the kernel to the process)
记住这两点很重要,因为这些IO Model的区别就是在两个阶段上各有不同的情况。
阻塞式I/O模型
产生阻塞的原因
linux进程调度算法-时间片调度算法
每个进程占用CPU一个时间片后被挂起
当前运行进程如果需要等待其他系统资源,且不是非阻塞方式运行,将进入等待状态





设置socket为非阻塞方式
函数fcntl
int flags;
flag=fcntl(sockfd,F_GETFL,0);
fcntl(sockfd,F_SETFL,flag|O_NONBLOCK);
函数ioctl
int on=1;
ioctl(sockfd,FIONBIO,&on);
非阻塞式I/O模型对4种I/O操作返回的错误
读操作
接收缓冲区无数据时返回EWOULDBLOCK
写操作
发送缓冲区无空间时返回EWOULDBLOCK
空间不够时部分拷贝,返回实际拷贝字节数
建立连接
启动3次握手,立刻返回错误EINPROGRESS
服务器客户端在同一主机上connect立即返回成功
接受连接
没有新连接返回EWOULDBLOCK
阻塞式I/O模型的超时控制
调用alarm函数设置超时
超时到达时产生SIGALARM信号中断I/O函数阻塞,对于4种产生阻塞的函数均有效
多次调用alarm时,产生的SIGALARM信号无法区分是哪一次超时引发的,无法实现超时控制
示例:alarmio.cpp

当用户进程调用了select,那么整个进程会被block,而同时,kernel会“监视”所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。这个时候用户进程再调用read操作,将数据从kernel拷贝到用户进程。
这个图和blocking IO的图其实并没有太大的不同,事实上,还更差一些。因为这里需要使用两个system call (select 和 recvfrom),而blocking IO只调用了一个system call (recvfrom)。但是,用select的优势在于它可以同时处理多个connection。(多说一句。所以,如果处理的连接数不是很高的话,使用select/epoll的web server不一定比使用multi-threading + blocking IO的web server性能更好,可能延迟还更大。select/epoll的优势并不是对于单个连接能处理得更快,而是在于能处理更多的连接。)
在IO multiplexing Model中,实际中,对于每一个socket,一般都设置成为non-blocking,但是,如上图所示,整个用户的process其实是一直被block的。只不过process是被select这个函数block,而不是被socket IO给block。
注意1:select函数返回结果中如果有文件可读了,那么进程就可以通过调用accept()或recv()来让kernel将位于内核中准备到的数据copy到用户区。
注意2: select的优势在于可以处理多个连接,不适用于单个连接
阻塞式I/O模型的超时控制
设置socket选项
设置SO_RCVTIMEO和SO_SNDTIMEO选项
设置了这两个选项之后,所有的读写操作可以保证在超时范围内返回
只需设置一次选项,对以后的读写操作均有效
不适用于accept和connect
示例:timeoutio.cpp


I/O模型详细解析的更多相关文章
- flex盒模型 详细解析
flex盒模型 详细解析 移动端页面布局,采用盒模型布局,效果很好 /* ============================================================ ...
- 5.java内存模型详细解析
一. java结构体系 Description of Java Conceptual Diagram(java结构) 我们经常说到JVM调优,JVM和JDK到底什么关系,大家知道么?这是java基础. ...
- 【转】JDK5.0中JVM堆模型、GC垃圾收集详细解析
基本概念 堆/Heap JVM管理的内存叫堆:在32Bit操作系统上有4G的限制,一般来说Windows下为2G,而Linux下为3G:64Bit的就没有这个限制.JVM初始分配的内存由-Xms指定, ...
- C++多态的实现及原理详细解析
C++多态的实现及原理详细解析 作者: 字体:[增加 减小] 类型:转载 C++的多态性用一句话概括就是:在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型 ...
- 目标检测从入门到精通—R-CNN详细解析(二)
R-CNN目标检测详细解析 <Rich feature hierarchies for Accurate Object Detection and Segmentation> Author ...
- java中JVM虚拟机内存模型详细说明
java中JVM虚拟机内存模型详细说明 2012-12-12 18:36:03| 分类: JAVA | 标签:java jvm 堆内存 虚拟机 |举报|字号 订阅 JVM的内部结构 ...
- java类生命周期详细解析
(一)详解java类的生命周期 引言 最近有位细心的朋友在阅读笔者的文章时,对java类的生命周期问题有一些疑惑,笔者打开百度搜了一下相关的问题,看到网上的资料很少有把这个问题讲明白的,主要是因为目前 ...
- springmvc 项目完整示例06 日志–log4j 参数详细解析 log4j如何配置
Log4j由三个重要的组件构成: 日志信息的优先级 日志信息的输出目的地 日志信息的输出格式 日志信息的优先级从高到低有ERROR.WARN. INFO.DEBUG,分别用来指定这条日志信息的重要程度 ...
- include_path详细解析
include_path详细解析 原文地址:http://www.laruence.com/2010/05/04/1450.html 1.php默认的包含路径为 .;C:\php\pear 即 ...
随机推荐
- 打印杨辉三角 --JS
var arr = new Array(); for(var i = 0 ;i < 6 ; i++){ if(i == 0){arr.push(1);} else if(i == 1){arr ...
- TRIZ系列-创新原理-26-复制原理
复制原理的详细表述例如以下:1)用简化的,廉价的复制品来替代易碎的或不方便操作的物体; 这样能够减少成本,提高可操作性.2)假设已经使用了可见光的复制品,那么使用红外光或者紫外光的复制品: ...
- 给eclipse配置sublime主题的背景
效果例如以下: 步骤: 1.假设你的Eclipse没有Marketplace的话,你自己装一个即可了:Help–>Install New Software–>add location:ht ...
- MobileNets总结
Google在2017年上半年发表了一篇关于可以运行在手机等移动设备上的神经网络结构--MobileNets.MobileNets是基于深度可分离卷积(depthwise separable conv ...
- 什么是PMI
项目管理协会 PMI PMI是世界领先的非盈利会员协会的项目管理专业机构 ,在全球185个国家有70多万会员和证书持有人.此外,PMI还是多个英文短语的缩写,较为著名的是采购经理指数PMI. 项目管理 ...
- websocket简单实例
只需要两个文件即可,一个服务端,一个前端,一下示例为模拟简单的聊天程序: 服务端: package com.test.websocket; import java.io.IOException; im ...
- atom添加eslint插件
在atom编辑器里添加插件,操作步骤如下:以atom-ide-vue插件为例 //切换到插件目录cd /Users/name/.atom/packages //将需要下载插件的源代码拉下来git cl ...
- 工作随笔——自动重发的凶手--feign
公司使用的feign(https://github.com/OpenFeign/feign)作为http客户端. 开发时debug后端程序,发现同一个请求会多次收到. 为了判断是谁在搞鬼,在客户端和服 ...
- ASP.NET.Core中使用AutoMapper
首先需要在NuGet中引用AutoMapper的类库 install-package AutoMapper install-package AutoMapper.Extensions.Micros ...
- ABP .Net Core Entity Framework迁移使用MySql数据库
一.迁移说明 ABP模板项目Entity Framework Core默认使用的是Sql Server,也很容易将数据库迁移到MySQL,步骤如下. 二.迁移MySQL步骤 1. 下载项目 请到 ht ...