04 基于Socket通讯的反应堆模型

基于Socket通讯的反应堆模型

反应堆是基于epoll的IO多路非阻塞模型,来实现的事件驱动,让我们按照递进的顺序进行分析,先来比较一下epoll非阻塞模型相对于多线程的优势所在。

一.多线程与epoll非阻塞

在理解Linux下的多线程模型与异步IO模型时,一定要理解线程与阻塞的开销其实是很大的,下面通过Linux下的测试来证明这一点:为了方便测试,让我们以Shell中的进程为例。

首先开启一个阻塞进程:read

 

然后使用ps -aux | grep read 查看一下它占用的资源: 

VSZ(Virtual Memory Size),虚拟内存大小,表明了该进程可以访问的所有内存,包括被交换的内存和共享库内存。

RSS( Resident Set Size )常驻内存集合大小,表示相应进程在RAM中占用了多少内存,并不包含在SWAP中占用的虚拟内存。即使是在内存中的使用了共享库的内存大小也一并计算在内,包含了完整的在stack和heap中的内存。

RSS更侧重于描述线程(进程)所实际占用的物理资源,你看,这样一个本身堆栈资源占用很小,更没有开辟共享内存的进行就占用了如此多的资源。

二.反应堆

顾名思义反应堆其名所要表达的含义就是速度快,那么它是怎样在epoll非阻塞IO模型的基础上提高效率的呢,主要有以下几点原因:

    1.反应堆使用自定义的结构体myevent_s对epoll操作进行了封装。添加了节点创建的时间点以提供链接检测;添加了回调函数以处理文件描述符所触发的事件。

struct myevent_s {
    int fd;                                                 //要监听的文件描述符
    int events;                                             //对应的监听事件
    void *arg;                                              //泛型参数
    void (*call_back)(int fd, int events, void *arg);       //回调函数
    int status;                                             //是否在监听:1->在红黑树上(监听), 0->不在(不监听)
    char buf[BUFLEN];
    int len;
    long last_active;                                       //记录每次加入红黑树 g_efd 的时间值
};

成员变量1 2 3 均为回调函数call_back的参数,参数5 表示文件描述符的状态,6 7为一个数组,最后的last_active是表示此文件描述符加入红黑树的时间,这个在前面的介绍中也提到过。

重要的是,arg参数传入的恰恰就是这个结构体本身的指针。

猜你喜欢

转载自blog.csdn.net/Hello_MyDream/article/details/86739547
04