IO多路复用实现方式

1.select实现

//1.创建表
fd_set readfds;
//清空表,局部变量,内部为随机值
FD_ZERO(&readfds);
//2.将关心的文件描述符添加到表中
FD_SET(0,&readfds);
//3.调用select函数检测事件
select(nfds;&readfds,NULL,NULL,NULL);
    //功能:监测那个或者那些文件描述符产生事件
    //nfds:检测的文件描述符个数
    //readfds:  读事件集合; //读(用的多)
    //writefds: 写事件集合;  //NULL表示不关心
    //exceptfds:异常事件集合;  
    //timeout:超时检测 1
//4.当文件描述符中的一个或者多个已经准备好进行I/O操作时候该函数才返回,结束阻塞
//5.判断哪一个文件或者那些文件描述符产生了事件(IO操作);
FD_ISSET(fd,&eadfds);
//6.做对应的逻辑处理;

 IO多路复用特点

1.一个进程做多只能监听1024个文件描述符

2.select被唤醒后需要轮询一遍驱动的poll函数,效率比较低(消耗CPU资源);

3.select每次会清空表,每次都需要拷贝用户空间的表到内核空间,效率低

poll实现

int poll(struct pollfd *fds, nfds_t nfds, int timeout);
   参p数:
   struct pollfd *fds
     关心的文件描述符数组struct pollfd fds[N];
   nfds:个数
   timeout: 超时检测
    毫秒级的:如果填1000,1秒
     如果-1,阻塞

 struct pollfd {
     int   fd;         /* 检测的文件描述符 */
     short events;     /* 检测事件 */
     short revents;    /* 调用poll函数返回填充的事件,poll函数一旦返回,将对应事件自动填充结构体这个成员。只需要判断这个成员的值就可以确定是否产生事件 */
 };
    事件: POLLIN :读事件
                POLLOUT : 写事件
               POLLERR:异常事件

poll实现IO多路复用的特点

1. 优化文件描述符个数的限制;(根据poll函数第一个函数的参数来定,如果监听的事件为1个,则结构体数组元素个数为1,如果想监听100个,那么这个结构体数组的元素个数就为100,由程序员自己来决定)

2. poll被唤醒之后需要重新轮询一遍驱动的poll函数,效率比较低

3. poll不需要重新构造文件描述符表,只需要从用户空间向内核空间拷贝一次数据即可

epoll实现

#include <sys/epoll.h>
int epoll_create(int size); 
功能:创建红黑树根节点
 参数:size:不作为实际意义值 >0 即可
返回值:成功时返回epoll文件描述符,失败时返回-1。

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
功能:控制epoll属性
    epfd:epoll_create函数的返回句柄。
    op:表示动作类型。有三个宏 来表示:
            EPOLL_CTL_ADD:注册新的fd到epfd中
            EPOLL_CTL_MOD:修改已注册fd的监听事件
            EPOLL_CTL_DEL:从epfd中删除一个fd
    Fd:需要监听的fd。
            event:告诉内核需要监听什么事件
            EPOLLIN:表示对应文件描述符可读
            EPOLLOUT:可写
            EPOLLPRI:有紧急数据可读;
            EPOLLERR:错误;
            EPOLLHUP:被挂断;
            EPOLLET:触发方式,边缘触发;(默认使用边缘触发)
             ET模式:表示状态的变化;
返回值:成功时返回0,失败时返回-1

typedef union epoll_data {
               void* ptr;(无效)
               int fd;
               uint32_t u32;
               uint64_t u64;
           } epoll_data_t;
           struct epoll_event {
               uint32_t events; / * Epoll事件* /
               epoll_data_t data; / *用户数据变量* /
};
//等待事件到来
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
功能:等待事件的产生,类似于select的用法
     epfd:句柄;
     events:用来保存从内核得到事件的集合;
     maxevents:表示每次能处理事件最大个数;
     timeout:超时时间,毫秒,0立即返回,-1阻塞
成功时返回发生事件的文件描述个数,失败时返回-1

epoll实现IO多路复用的特点

•监听的最大的文件描述符没有个数限制(理论上,取决与你自己的系统)

•异步I/OEpoll当有事件产生被唤醒之后,文件描述符主动调用callback(回调函数)函数直接拿到唤醒的文件描述符,不需要轮询,效率高

epoll不需要重新构造文件描述符表,只需要从用户空间向内核空间拷贝一次数据即可.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值