源地址:http://blog.csdn.net/jnu_simba/article/details/9070955

一、五种I/O模型

1、阻塞I/O

我们在前面所说的I/O模型都是阻塞I/O,即调用recv系统调用,如果没有数据则阻塞等待,当数据到来则将数据从内核空间(套接口缓冲区)拷贝到用户空间(recv函数提供的buf),然后recv返回,进行数据处理。

2、非阻塞I/O

我们可以使用 fcntl(fd, F_SETFL, flag | O_NONBLOCK); 将套接字标志变成非阻塞,调用recv,如果设备暂时没有数据可读就返回-1,同时置errno为EWOULDBLOCK(或者EAGAIN,这两个宏定义的值相同),表示本来应该阻塞在这里(would block,虚拟语气),事实上并没有阻塞而是直接返回错误,调用者应该试着再读一次(again)。这种行为方式称为轮询(Poll),调用者只是查询一下,而不是阻塞在这里死等,这样可以同时监视多个设备:

while(1)

{

非阻塞read(设备1);

if(设备1有数据到达)

处理数据;

非阻塞read(设备2);

if(设备2有数据到达)

处理数据;

..............................

}

如果read(设备1)是阻塞的,那么只要设备1没有数据到达就会一直阻塞在设备1的read调用上,即使设备2有数据到达也不能处理,使用非阻塞I/O就可以避免设备2得不到及时处理。

非阻塞I/O有一个缺点,如果所有设备都一直没有数据到达,调用者需要反复查询做无用功,如果阻塞在那里,操作系统可以调度别的进程执行,就不会做无用功了,在实际应用中非阻塞I/O模型比较少用,经常与IO multiplexing 一起使用。

3、I/O复用

用select来管理多个I/O,当没有数据时select阻塞,如果在超时时间内数据到来则select返回,再调用recv进行数据的复制,recv返回后处理数据。

4、信号驱动I/O

先注册SIGIO信号的处理函数,进程继续执行其他操作,当数据到来时会发送SIGIO信号给进程,然后可以在信号处理函数中调用recv进行数据的复制,然后recv返回进行数据处理。

5、异步I/O

aio_read 函数也会提供一个buf,系统调用进入内核,如果没有数据则立即返回,进程继续执行其他操作,所以叫异步I/O,当数据到来时内核自动复制数据,然后推送给用户空间,通过在aio_read中指定的信号通知进程,让其处理数据。异步I/O跟信号驱动I/O的不同之处在于,它不用调用recv进行数据的复制,如果将后者比做”拉pull“,则前者可以认为是”push推“,push的效率会高点,其实异步I/O跟windows下面的完成端口差不多,但aio_read的实现或多或少存在问题,用得也比较少。

二、select函数简介

/* According to POSIX.1-2001 */        #include <sys/select.h>        /* According to earlier standards */        #include <sys/time.h>        #include <sys/types.h>        #include <unistd.h>

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

参数1:读写异常集合中的文件描述符的最大值加1;

参数2:读集合,关心可读事件;

套接口缓冲区有数据可读 对等连接的写一半关闭。即接收到FIN段,读操作将返回0 如果是监听套接口,已完成连接队列不为空时。 套接口上发生了一个错误待处理,错误可以通过getsockopt指定SO_ERROR选项来获取。

参数3:写集合,关心可写事件;

套接口发送缓冲区有空间容纳数据。

对等连接的读一半关闭。即收到RST段之后,再次调用write操作。

套接口上发生了一个错误待处理,错误可以通过getsockopt指定SO_ERROR选项来获取。

参数4:异常集合,关心异常事件;

套接口存在带外数据(TCP头部 URG标志,16位紧急指针字段)

参数5:超时时间结构体

对于参数2,3,4来说,如果不关心对应事件则设置为NULL即可。注意5个参数都是输入输出参数,即select返回时可能对其进行了修改,比如集合被修改以便标记哪些套接口发生了事件,时间结构体的传出参数是剩余的时间,如果设置为NULL表示永不超时。用select管理多个I/O,select阻塞等待,一旦其中的一个或多个I/O检测到我们所感兴趣的事件,select函数返回,返回值为检测到的事件个数,并且返回哪些I/O发送了事件,遍历这些事件,进而处理事件。注意当select阻塞返回后,此时调用read/write 是不会阻塞的,因为正是有可读可写事件发生才导致select 返回,也可以认为是select 提前阻塞了。
下面是4个可以对集合进行操作的宏: void FD_CLR(int fd, fd_set *set); // 清除出集合 int  FD_ISSET(int fd, fd_set *set); // 判断是否在集合中 void FD_SET(int fd, fd_set *set); // 添加进集合中 void FD_ZERO(fd_set *set); // 将集合清零

select函数的举例应用看这里

参考:

《Linux C 编程一站式学习》

《TCP/IP详解 卷一》

《UNP》

转:五种I/O模型和select函数简介的更多相关文章

  1. 五种I/O模型和select函数简介

    一.五种I/O模型 1.阻塞I/O 我们在前面所说的I/O模型都是阻塞I/O,即调用recv系统调用,如果没有数据则阻塞等待,当数据到来则将数据从内核空间(套接口缓冲区)拷贝到用户空间(recv函数提 ...

  2. 五种I/O 模式,select、epoll方法的理解,BIO、NIO、AIO理解 相关文章

    一.io方式 Linux网络编程 五种I/O 模式及select.epoll方法的理解 web优化必须了解的原理之I/o的五种模型和web的三种工作模式 五种I/O 模式——阻塞(默认IO模式),非阻 ...

  3. IO五种模型和select与epoll工作原理(引入nginx)

    用户速度体验的1-3-10原则 性能影响 有很多研究都表明,性能对用户的行为有很大的影响: 79%的用户表示不太可能再次打开一个缓慢的网站 47%的用户期望网页能在2秒钟以内加载 40%的用户 ...

  4. 比较一下Linux下的Epoll模型和select模型的区别

    一. select 模型(apache的常用) 1. 最大并发数限制,因为一个进程所打开的 FD (文件描述符)是有限制的,由 FD_SETSIZE 设置,默认值是 1024/2048 ,因此 Sel ...

  5. select()函数 的学习

    select()的介绍 全是拷贝的如下文章: https://www.cnblogs.com/wenqiang/p/5508541.html select()函数的用例代码摘录如下文章: https: ...

  6. 面试中常问的五种IO模型和BIO,NIO,AIO

    一,五种IO模型: 一个IO操作可以分为两个步骤:发起IO请求和实际的IO操作例如:1.操作系统的一次写操作分为两步:第一步,将数据从用户空间拷贝到系统空间:第二步,从系统空间往网卡写.2.一次读操作 ...

  7. mysql中select五种子句和统计函数

    select 五种子句顺序 where 条件 group by 分组 having 把结果进行再次筛选 order by  排序 limit  取出条目 统计函数  max(列名)  求最大 min( ...

  8. 04: 事件驱动、五种I/O操作、I/O多路复用select和epoll

    网络编程其他篇 目录: 1.1 事件驱动 1.2 五种I/O操作 1.3 I/O 多路复用之select.poll.epoll详解 1.1 事件驱动返回顶部 1.什么是事件驱动  定义:就是根据不同事 ...

  9. linux第7天 I/O的五种模型, select

    服务器端避免僵尸进程的方法: 1)通过忽略SIGCHLD信号,解决僵尸进程 signal(SIGCHLD, SIG_IGN) 2)通过wait方法,解决僵尸进程 signal(SIGCHLD, han ...

随机推荐

  1. idea在ssm项目中引入本地的jar

    在对应的lib下,右键找到add...,即可

  2. 004-Java进制转换

    整型数据共有4中进制形式 二进制(binary):以0b或者0B开头 十进制(decimal) 八进制(octal):以数字0开头 十六进制(hex):以0x或者0X开头 二进制数据包含原码反码和补码 ...

  3. cms系统视频分享

    cms_001-CMS系统功能需求简介-1.avicms_002-如何采用用例分析方法来理解需求-1.avicms_003-后台管理系统用例-1.avicms_004-实现验证码的初步思路-1.avi ...

  4. iOS开发系列-Runtime运用场景

    概述 Runtime 又叫运行时,是一套底层的 C 语言 API,其为 iOS 内部的核心之一,我们平时编写的 OC 代码,底层都是基于它来实现的. 调用runtimeAPI需要导入都文件#impor ...

  5. SpringCloud学习笔记《---06 Config 分布式配置中心---》基础篇

  6. 2018-12-1-WPF-修改-ItemContainerStyle-鼠标移动到未选中项效果和选中项背景

    title author date CreateTime categories WPF 修改 ItemContainerStyle 鼠标移动到未选中项效果和选中项背景 lindexi 2018-12- ...

  7. Hadoop Pig组件

  8. Sublime Text自定制代码片段(Code Snippets)

    在编写代码的整个过程中,开发人员经常会一次又一次的改写或者重用相同的代码段,消除这种重复过程的方法之一是把我们经常用到的代码保存成代码片段(snippets),这使得我们可以方便的检索和使用它们. 为 ...

  9. if else 和 swith效率比较

    读大话设计模式,开头的毛病代码用if else实现了计算器,说计算机做了三次无用功,优化后是用switch,那么switch为什么比if else效率高呢, 百度找了几个说是底层算法不一样,找了一个比 ...

  10. undertow服务器

    参考地址:http://undertow.io/undertow-docs/undertow-docs-1.3.0/index.html 1.引入相关jar <dependencies> ...