漫谈io复用和高性能服务框架

前言:这篇博客可能会写的有点杂乱,毕竟是想到哪里写到哪里,至少算是一个总结性的文章。     一.IO复用的生     二.IO复用实现     三.统一事件源     四.Reactor模型     五.有限状态机一.IO复用的生​ 首先我们先说说不用IO复用时,我们所谓的并发服务器的极限。简单的想,我们可以用一个线程来负责一个链接,但是线程个数又不是可以无限增大的...
摘要由CSDN通过智能技术生成
前言:这篇博客可能会写的有点杂乱,毕竟是想到哪里写到哪里,至少算是一个总结性的文章。

     一.IO复用的生

     二.IO复用实现

     三.统一事件源

     四.Reactor模型

     五.有限状态机

一.IO复用的生

​ 首先我们先说说不用IO复用时,我们所谓的并发服务器的极限。简单的想,我们可以用一个线程来负责一个链接,但是线程个数又不是可以无限增大的,在简单的线程间的时间调度虽然可以说很廉价,但是廉价的东西乘以庞大的基数带来的结果是昂贵的。当不活跃的链接的占用了大部分,执行效率会变得更低。

​ 连接上的消息处理,可以分为两个阶段,即等待消息准备好和消息处理,当我们使用阻塞模型的时候,我们将这两个部分合二为一,从而一个链接只能捆绑一个链接,在需要的时候唤醒,不需要的时候睡眠。

​ 但是如果我们把等待消息准备好和消息处理分开,我们就不用频繁的唤醒和睡眠的进程,我们这时候也就需要一个线程,它的工作就是不断询问链接消息是否准备好,一旦准备好,它就将一个链接唤醒,直接创造/拿取一个线程对其进行消息的处理,进而可以减少时间调度和不活跃链接的代价。

​ 这就是IO多路复用了。多路复用就是处理等待消息准备好这件事的,但它可以同时处理多个连接!它也可能“等待”,所以它也会导致线程睡眠,然而这不要紧,因为它一对多、它可以监控所有连接。这样,当我们的线程被唤醒执行时,就一定是有一些连接准备好被我们的代码执行了,这是有效率的!没有那么多个线程都在争抢处理“等待消息准备好”阶段,整个世界终于清净了!

<!-- more -->

二.IO复用实现

​ IO复用有多种实现,但是常用的就是epoll。

  • select

    select系统原型如下

    #include <sys/select.h>
    int select(int nfds, fd_set *readfds, fd_set *writefds,
                      fd_set *exceptfds, struct timeval *timeout);

    nfds通常要在监听的文件描述符中最大的加1,因为计数是从0开始的:-D

    readfds writefds exceptfds名如其意,指的是可读,可写,异常时间对应的文件描述符集合

    select使用的轮寻模式,在开始的时候要指明监听事件,函数成功返回后会返回就绪事件。从阅读fd_set结构体代码可知,fd_set监听事件上限为1024,包含一个结构体数组,数组的元素的每一位对应一个文件描述符。

    select提供了以下的函数,方便位操作

           void FD_CLR(int fd, fd_set *set);      //clear fd in set
           int  FD_ISSET(int fd, fd_set *set);    //judge fd is set 
           void FD_SET(int fd, fd_set *set);      //add fd into set
           void FD_ZERO(fd_set *set);            // clear all of set 
  • poll

    poll原型如下

           #include <poll.h>
           int poll(struct pollfd *fds, nfds_t nfds, int timeout)        
           struct pollfd {
                   int   fd;         /* file descriptor */
                   short events;     /* requested events */
                   short revents;    /* returned events */
               };

    ​ 看到pollfd的结构,我们就可以看出它还是轮寻模式,不过有个一好处就是他可以在监听事件不发生改变的情况下,可以不像select一样,在函数开始不断设置事件。但是他还是需要一个个访问每个监听事件,即fds的元素。

    下面是events所包含的部分重要事件

    POLLIN      There is data to read.                  
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值