网络I/O_05多路复用器

1.linux 程序员手册

(1)安装man-pages(linux 程序员手册)

#yum install -y man-pages

#man 2 select //1用户命令,2系统调用 3例程,库函数 4设备,/dev目录文件 5文件格式描述 6游戏 7杂项 8系统管理员工具,root权限 9其他 n新文档,o老文档,l本地文档

(2)查看linux内核版本

#uname -a

2.select

        使用select是先对操作的fd进行查询,是否可读,可写,异常等,查到结果之后才发起真正的IO操作

(1)手册:

学习最好的文档应该是官方文档,可以自己查阅

#man 2 select

(2)函数:

int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);
 
    nfds:nfds是三个集合中编号最高的文件描述符数加1。
    readfds:返回可读的fd集合
    writefds:返回可读的fd集合
    exceptfds:返回异常的fd集合
    timeout:超时时间:0立刻返回(轮询很有用),null一直阻塞(中断信号可以结束),>0超时返回

主要工作:

        A.内核收到数据包到达信号,会调用select()

        B.select()会把用户空间的fds拷贝到内核空间,然后遍历fds,找到有数据的fd标记好

        C.将内核空间fds的结果,拷贝回给用户空间(可读,可写,异常集合)

        D.内核再发中断信号告诉用户进程,可以来read() fd的数据了

(3)优缺点:

        优:多个fd集中拷贝,一次select()只需拷贝一次,减少用户态和内核态之间切换

        缺:

        A. 监听fd数量最大1024

        B. 每次都需要遍历全量fd才知道那个有数据到达

3.poll

        poll和select(2)类似,都是等待一组文件描述符中的一个准备就绪

(1)手册

#man 2 poll

(2)函数

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


fds: pollfd的结构体数组,存放fd的
     struct pollfd { //存放fds参数的结构体
               int   fd;         /* file descriptor */   //文件描述符
               short events;     /* requested events */  //设置我们希望发生的事件(可读,可写,异常)
               short revents;    /* returned events */   // 实际发生的事件(由内核填充:可读,可写,异常)
           };
nfds:调用方指定fds数组中的项数
timeout:超时时间

        poll和select(2)类似,都是等待一组文件描述符中的一个准备就绪

        区别:

        poll遍历长度不限制

        select遍历长度限制1024(和linux设置宏定义有关)

(3)优缺点

        :遍历长度不限制了

        :A.需要遍历才知道fd是否可读可写

4.epoll

(1)手册

#man 2 epoll_create/epoll_ctl/epoll_wait

(2)函数

int epoll_create(int size); 
size:初始监听fds大小,可动态扩展
//1.创建一个epfd,申请空间
//2.初始化一颗红黑树,用于存放所以监听的fds
//3.初始化一个就绪list链表,后面监听到有数据到达的就添加到这里


int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
epfd:epoll_create创建的epfd,用于epoll事件操作
op:epfd绑定fd动作,新增,修改,删除
fd: socket连接分配的fd,要监听的fd
event:epoll_event 要监听事件(EPOLLIN|EPOLLET可读,可写等)
//作用:注册一个监听事件(将epfd,fd,事件绑一起)
//1.将用户空间的fd拷贝到内核,根据op动作:操作插入,删除,或修改,结果保存在红黑树上
//2.当中断信号来时,符合监听事件,内核向准备就绪链表中插入数据


int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
//1.等待事件发生,监听就绪链表
//2.有数据到达时,通知用户进程拷贝数据
struct epoll_event {
    __uint32_t events;
    epoll_data_t data;
};

(3)select,poll,epoll 比较

多路复用器

select

poll

epoll

fd存储数据结构

数组

链表

红黑树+就绪链表(双向链表)

遍历时间复杂度

O(n)

O(n)

O(1)

工作模式

轮询

轮询

信号驱动

前面有说过

Windows的IOCP实现了真正的异步IO

Linux系统下,异步IO模型在2.6版本才引入,目前并不完善,其底层实现仍使用epoll

大多数的高并发服务器端的程序,一般都是基于Linux系统的,因此大多还采用IO多路复用模型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值