多路复用IO


一、IO模型介绍

    1、阻塞IO,常用的scanf、printf、read、write、cout、cin
    2、非阻塞IO,recv、send和Qt中read、write 
    3、多路复用IO   
    4、信号驱动IO    
    5、异步IO

二、多路复用IO

在不创建新的进程和线程的情况下监控多个文件描述符,多应用于网络编程时一个服务端程序为多个客户端程序提供服务,多用于在业务逻辑简单,客户端需要的服务时间短,响应时间无太高要求的场景。

三、使用select函数实现多路复用IO

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

功能:监控多个文件描述符的 读、写、异常 操作
nfds:最大文件描述符+1
readfds:监控读操作文件描述符集合
writefds:监控写操作文件描述符集合
exceptfds:监控异常操作文件描述符集合
timeout:设置超时时间
返回值:监控到文件描述符的个数,超时返回0,出错返回-1

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设计不合理的地方:
    1、所有被监视的文件描述符都需要检查(效率不高)。
    2、每次调用select都需要向它传递新的监视对象信息 

select的优点是:
    程序的兼容性高  

int pselect(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, const struct timespec *timeout, const sigset_t *sigmask);
功能:与select的功能大致类似
区别:
    1、select函数用的timeout参数,是一个timeval的结构体(包含秒和微秒),然而pselect用的是一个timespec结构体(包含秒和纳秒)

    2、select函数可能会为了指示还剩多长时间而更新timeout参数,然而pselect不会改变timeout参数

    3、select函数没有sigmask参数,当pselect的sigmask参数为null时,两者行为时一致的。有sigmask的时候,pselect相当于如下的select()函数,在进入select()函数之前手动将信号的掩码改变,并保存之前的掩码值;select()函数执行之后,再恢复为之前的信号掩码值。

四、使用poll函数实现多路复用IO

int poll(struct pollfd *fds, nfds_t nfds, int timeout);
fds:所有被监控的文件描述符结构体数组
nfds:数组的长度
timeout:超时时间,毫秒单位

struct pollfd
{
    int fd;     //被监控文件描述符
    short events; // 等待的需要监控事件
    short revents; // 实际发生了的事件,也就是返回结果
};

events:
    POLLIN      普通或优先级带数据可读
    POLLPRI     高优先级数据可读   
    POLLOUT     普通数据可写
    POLLRDHUP   对方socket关闭
    POLLERR     发生错误
    POLLHUP     发生挂起
    POLLNVAL    描述字不是一个打开的文件

poll特点:
    1.文件描述符没有最大限制 -数据结构:链表
    2.每次调用都需要将fd集合从用户态拷贝到内核态 
    3.内核需要遍历所有fd,效率低

五、使用epoll函数实现多路复IO

int epoll_create(int size);
功能:创建用于保存被监控文件描述符的空间

int epoll_ctl(int epfd, int op, int fd, struct  epoll_event *event);  
功能:向文件中添加、删除,文件描述符

int epoll_wait(int epfd, struct epoll_event *events,  int maxevents, int timeout); 
功能:监控文件描述符
1.文件描述符没有最大限制 --数据结构:红黑树
2.只需拷贝一次fd到内核态 
3.内核只需判断就绪链表是否为空,不需要遍历所有fd,效率高,并把就绪fd拷贝到用户空间

Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source Love丶伊卡洛斯 !
评论
 Previous
Linux下嵌入式Web服务器BOA和CGI编程开发 Linux下嵌入式Web服务器BOA和CGI编程开发
一、环境搭建操作系统:Ubuntu12.04 LTSboa下载地址(但是我找不到…):http://www.boa.org/我是其他网站找到的资源,但是忘了网址了,所以我直接上云盘资源链接: https://pan.baidu.com/s/
2019-10-17
Next 
C++基础知识(四) C++基础知识(四)
面向过程编程: 关注是问题解决的过程步骤,算法 面向对象编程: 关注的是谁能解决问题(类),需要什么样的数据(成员变量),具备什么样的技能(成员函数)才能解决问题。 抽象:找出一个能够解决问题的“对象”(观察研究对象),找
2019-09-19
  TOC