简介

IO复用技术,简单来说就是同时监听多个描述符。在没有用到IO复用以前,只能是一个线程或一个

线程去监听,服务端同时有多个连接的时候,需要创建多个线程或者进程。而且,并不是所有的连

接是一直在传输这数据,可能只是连接后啥都没干,如果这样,进程就啥都没干。

现在有了IO复用技术,只有描述符就绪的时候才去处理,这样就很方便了。

IO复用的使用大概是这样:

设置要监听的描述符以及需要监听的事件



监听事件,一直阻塞直到有描述符就绪



遍历所有就绪的描述符,并进行相应处理

IO复用有三种方式,分别是select, poll, epoll

select

select函数原型

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

参数详解:

nfds:nfds参数指定的是被监听的文件描述符的总数,一般设置成最大的描述符加上1,因为描述

符是从0开始的。

readfds:需要监听读事件的描述符集

writefds:需要监听写事件的描述符集

exceptfds:需要监听异常事件的描述符集

timeout:设置超时时间,如果传递的是NULL,则select会一直阻塞

一般的使用步骤:

1 设置FD_SET集合,如果要同时监听多种事件,则需要使用多个描述符集合

2 调用select,select会通过更改描述集,只留下准备好的描述符,所以需要在调用前保留一份

3 同时描述符需要在数组中存储一份,这个通过遍历数组和FD_ISSET来判断是否准备好,若准备好则去执行相关任务

缺点:

select 最大支持的描述符有限一般是1024。

同时select内部的操作是等待描述符集合,必然需要进入到内核态,所以,每次需要把描述符集合

从用户空间拷贝到内核空间,这样是特别消耗资源的,同时select这种方式,只保留准备好的描述符

这样,使用特别不方便,每次还需要对数组进行遍历来判断描述符是否在准备好的集合当中。

poll

poll相对于select的优点就是解决了描述符的限制问题,但是性能并不好。poll也是需要通过遍历

的方式来判断描述符的准备状态,当描述符较多时,则就尴尬了。

函数原型:

int poll(struct pollfd *fds, nfd_t nfds, int timeout);

struct pollfd

{

int fd; //文件描述符

short events; //注册的事件

short revents; //实际发生的事件

}

参数详解:

fds:需要监听的数组,数组里的每个结构体都设置好描述符和需要注册的事件,如果有多个,使用或('|')操作符

nfds:数组的长度

timeout:指定超时值,单位是毫秒

常用的宏:

POLLIN:数据(包括普通数据和优先数据)可读

POLLOUT:数据(包括普通数据和优先数据)可写

epoll

epoll 相比select和poll不同,epoll将监听的描述符集存放在内核区,免去了select和poll每次调用

都需要将描述符集从用户空间拷贝到内核空间的消耗。同时epoll的对于已经准备好的描述符处理比较方便。

还增加了一些新的特性,比如ET和LT两种触发模式,

epoll提供了三个函数:

int epoll_create(int size);

epoll_create用来创建一个描述符,指向内核创建的描述符集。之后的操作都通过描述符来操作。

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

epfd:传入的是指向描述符集的描述符

op:有三个宏:

EPOLL_CTL_ADD: 添加fd上的注册事件

EPOLL_CTL_MOD: 修改fd上的注册事件

EPOLL_CTL_DEL: 删除fd上的注册事件

fd:需要操作的描述符

event:

struct epoll_event

{

__uint32_t events; //epoll事件

epoll_data_t data; //用户数据

}

typedef union epoll_data_t

{

void *ptr;

int fd;

uint32_t u32;

uint64_t u64;

} epoll_data_t;

int  epoll_wait(int epfd, struct epoll_event* events, int maxevents, int timeout);

函数详解:

返回值:返回准备好的描述符的个数

epfd:指向描述符集的描述符

events:这里是作为函数传出使用,epoll_wait之后会设置这个数组,之后再遍历这个数组即可

maxevents:指定最多监听的描述符的个数

timeout:超时时间,和poll相同。

epoll有两种触发模式,一种是LT(条件触发)一种ET(边沿触发)

LT条件触发:

当满足某个条件,就会触发,如果没有去处理,会一直去触发

LT是默认的触发方式

ET边沿触发:

当满足某个条件之后触发一次,如果未处理,就不管了。

在设置触发事件的时候或上 EPOLLET

那么问题来了?

如果之后还有数据到来,还会触发吗?

如果会,那么之前未处理的数据还在吗,会丢弃吗?

如果之后还有新的数据来,依然会触发,同时之前缓冲的数据可以一块读出来。

IO复用三种方式的更多相关文章

  1. IO多路复用三种方式select/poll/epoll

    select多并发socket例子: #_*_coding:utf-8_*_ __author__ = 'Alex Li' import select import socket import sys ...

  2. Linux就这个范儿 第15章 七种武器 linux 同步IO: sync、fsync与fdatasync Linux中的内存大页面huge page/large page David Cutler Linux读写内存数据的三种方式

    Linux就这个范儿 第15章 七种武器  linux 同步IO: sync.fsync与fdatasync   Linux中的内存大页面huge page/large page  David Cut ...

  3. Java基础知识强化之IO流笔记62:三种方式实现键盘录入

    1. 三种方式实现键盘录入     System.in 标准输入流.是从键盘获取数据的 键盘录入数据三种方式:  A:main方法的args接收参数.  java HelloWorld hello w ...

  4. 监视EntityFramework中的sql流转你需要知道的三种方式Log,SqlServerProfile, EFProfile

    大家在学习entityframework的时候,都知道那linq写的叫一个爽,再也不用区分不同RDMS的sql版本差异了,但是呢,高效率带来了差灵活性,我们 无法控制sql的生成策略,所以必须不要让自 ...

  5. 0036 Java学习笔记-多线程-创建线程的三种方式

    创建线程 创建线程的三种方式: 继承java.lang.Thread 实现java.lang.Runnable接口 实现java.util.concurrent.Callable接口 所有的线程对象都 ...

  6. android中解析文件的三种方式

    android中解析文件的三种方式     好久没有动手写点东西了,最近在研究android的相关技术,现在就android中解析文件的三种方式做以下总结.其主要有:SAX(Simple API fo ...

  7. Java Class类以及获取Class实例的三种方式

    T - 由此 Class 对象建模的类的类型.例如,String.class 的类型是Class<String>.如果将被建模的类未知,则使用Class<?>.   publi ...

  8. 三种方式上传文件-Java

    前言:负责,因为该项目他(jetty嵌入式开始SpringMvc)实现文件上传的必要性,并拥有java文件上传这一块还没有被曝光.并 Http 更多晦涩协议.因此,这种渐进的方式来学习和实践上载文件的 ...

  9. 使用Net.Mail、CDO组件、JMail组件三种方式发送邮件

    原文:使用Net.Mail.CDO组件.JMail组件三种方式发送邮件 一.使用Net.Mail 需要服务器认证,大部分服务器端口为25. { MailMessage mailMsg = mailMs ...

随机推荐

  1. jQuery hover事件

    hover(over,out)一个模仿悬停事件(鼠标移动到一个对象上面及移出这个对象)的方法.这是一个自定义的方法,它为频繁使用的任务提供了一种"保持在其中"的状态. 当鼠标移动到 ...

  2. Linux系统virtualbox + ubuntu + xshell 问题与注意事项

    序言:ubuntu闭源软件太多,一般不推荐使用:没钱可以使用centos.debian:有钱使用redhat 目前主流和常用的Linux版本主要有:1.Redhat 版本5.5和6.0最新:培训.学习 ...

  3. 51nod1073(约瑟夫环)

    题目链接: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1073 题意: 中文题诶~ 思路: 直接模拟的话O(n*k)的 ...

  4. Android -- Activity,Fragment lifecycle

    Activity Lifecyce Fragment Lifecycle: 程序运行: 09-16 13:59:22.883 19022-19022/com.example.android.archi ...

  5. C#回顾 –6.特性

    1.特性是什么?  Attribute 用来对类.属性.方法等标注额外的信息,贴一个标签(附着物)  通俗:给 类 或 类成员 贴一个标签,就像航空部为你的行李贴一个标签一样  个人理解,特性就是修饰 ...

  6. iOS中类别的使用

    类别的三大作用1.给现有的类增加方法,可以增加 对象方法,也可以增加静态方法. 如果增加的方法是此类本来就有的方法,那么,此方法有可能会把原方法覆盖,也有可能不会覆盖. 类别只能增加现有类的方法,不能 ...

  7. NOI 题库 8465

    8465  马走日 描述 马在中国象棋以日字形规则移动. 请编写一段程序,给定n*m大小的棋盘,以及马的初始位置(x,y),要求不能重复经过棋盘上的同一个点,计算马可以有多少途径遍历棋盘上的所有点. ...

  8. uri不能处理结尾为点的url的问题

    最近需要和某公司进行接口对接,发现用WebClient获取URL结尾带.的资源,会出404错误.但是用IE还有其它浏览器访问此资源,还能找到它.很神奇. 于是,我百度了,找到的一堆都是说此url不规范 ...

  9. ZeroMQ接口函数之 :zmq_msg_recv - 从一个socket中接受一个消息帧

    ZeroMQ 官方地址 :http://api.zeromq.org/4-2:zmq_msg_recv zmq_msg_recv(3) ØMQ Manual - ØMQ/3.2.5 Name zmq_ ...

  10. 02.JavaScript基础下

    运算符 算术:+ 加.- 减.* 乘./ 除.% 取模 实例:隔行变色.秒转时间 赋值:=.+=.-=.*=./=.%= 关系:<.>.<=.>=.==.===.!=(不等). ...