IO多路复用

一.构建tcp并发服务器

单循环服务器:服务器同一时刻只能响应一个客户端的请求
并发服务器:服务器在同一时刻可以响应多个客户端的请求

构建TCP并发服务器:让TCP服务端具备同时响应多个客户端的能力。

1. 多进程
    资源消耗大,同资源平台下,并发量小。
2. 多线程
     创建线程、进程,比较耗时
3. 线程池
     提前预创建大量线程,避免任务执行过程中创建线程的耗时

4.IO多路复用

在不创建新的进程和线程的前提下,可以在一个进程中同时监测多个IO(fd/sockfd/connfd)。

优势:节省资源
不足:不利于处理比较耗时,延时比较长的任务

(IO多路复用包含select,poll,epoll)

流程:

1.创建文件描述符集合
2.将关注的文件描述符加入到集合
3.等待IO事件到达
4.根据不同的I0事件处理不同的任务

二.IO多路复用
(1)select

        select使用位图管理文件描述符,最多允许同时检测1024个文件描述符(有上限)

        文件描述符集合在应用层创建,需要实现应用层和内核层的反复拷贝

        需要应用层对集合表进行遍历,寻找到达事件

        只能工作在水平触发模式(低速模式),不能工作在边沿触发模式

int select(int nfds,fd set *readfds,fd set *writefds.fd set *exceptfds,stuct timeval *tine out);
功能:阻塞等待IO事件,返回事件结果参数:
    nfds:关注的最大文件描述符+1

    readfds:文件描述符读事件集合表

    wiitefils:写事件集合表

    exceptfds:其他事件集合表

    timeout:超时时间
    NULL:不设置超时

返回值:

成功:返回到达的事件个数

失败:-1 

0:超时事件到达但没有返回文件

 void FD_CLR(int fd, fd_set *set);//移除fd
 int  FD_ISSET(int fd, fd_set *set);//判断该文件描述符是否被置起
 void FD_SET(int fd, fd_set *set);//将fd放到文件描述符集合中
 void FD_ZERO(fd_set *set);//清零   

(2)poll
1.使用链表管理文件描述符,对监测的文件描述符没有上限限制.

2.文件描述符集尽在应用层创建,需要实现应用层和内核层的反复拷贝

3.需要应用层对集合表进行遍历,寻找到达的事件

4.只能工作在水平触发模式(低速模式),不能工作在边沿触发模式(高速模式)

(3)epoll
1.使用树型结构(红黑树)管理文件描述符,提高查找效率

        树型结构的特点:提高数据的查找效率, 遍历时间复杂度为O(2logN)

2.文件描述符集合创建在内核,避免了应用层和内核层的数据拷贝

3.直接向应用层返回到达的io事件的集合,不需要进行遍历查找

操作流程:
1.创建文件描述符集合了 epoll_create();

2.将关注的文件描述符加入到集合epoll_ctl();

3.等待IO事件到达epoll_wait();

4.根据不同的IO事件处理不同的任务

int epoll_create(int size)
功能:创建并打开一个epoll的文件描述符集合
参数:

size:最多允许监测的文件描述的个数

返回值:

成功:代表集合的文件描述符

失败:-1

int epoll_ctl(int epfd,int op,int fd,struct epoll_event *event);
功能:对文件描述符集合进行操作
参数:

epfd:要操作的文件描述符集合

op:进行什么操作

        EPOLL_CTL_ADD:向集合添加

        EPOLL_CTL_MOD:修改集合

        EPOLL_CTL_DEL:从集合删除

fd:要操作的文件描述符

event:事件的结构体,在op= EPOLL_CTL_ADD或者 EPOLL_CTL_MOD时使用,

 typedef union epoll_data {
               void        *ptr;
               int          fd;
               uint32_t     u32;
               uint64_t     u64;
           } epoll_data_t;

           struct epoll_event {
               uint32_t     events;      /* Epoll events */
               epoll_data_t data;        /* User data variable */
           };

events:
EPOLLIN:对文件描述符的读事件

EPOLLOUT:对文件描述符的写事件

data: fd:操作的事件对应的文件描述符

返回值:

  成功:0

  失败:-1

 int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
功能:开始监测IO事件,并返回检测到的结果
参数:

epfd:要监测的文件描述符集合

event:保存epoll_wait监测到的到达事件的结果

maxevents:最多监测的事件个数

timeout:超过时间

返回值:

成功:返回到达的IO事件的个数

          失败:-1

          0:超时时间但没有事件到达

你可能感兴趣的:(服务器,运维)