Libevent工作流程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/plyb602260747/article/details/79964421
最近用到libevent,由于以前没用过这个东东,只是参考别人的代码写了一个基于socket的c/s,收获就是写这个东东第一步干嘛,第二步干嘛,无脑的将需要的函数运用了一遍,但是具体它是如何工作一无所知。
今天查阅资料对大体的工作流程梳理一下。未阅读源码,下面的东西是基于查阅资料然后总结的。
  1. libevnet介绍:
    Libevent是一个轻量级的开源的基于事件驱动的高性能网络库。
  2. 事件驱动介绍:
    所谓事件驱动,以电脑为例,就是你点什么按钮(即产生什么事件),电脑执行什么操作(即调用什么函数)
  3. libevent框架:
    Libevent框架本质上是一个典型的Reactor模式,所以只需要弄懂Reactor模型,libevent就八九不离十了。
    Reactor模式,是一种事件驱动机制。应用程序需要提供相应的接口并注册到Reactor上,如果相应的事件发生,Reactor将主动调用应用程序注册的接口,这些接口又称为“回调函数”。
    在Libevent中也是一样,向Libevent框架注册相应的事件和回调函数;当这些事件发生时,Libevent会调用这些回调函数处理相应的事件(I/O读写、定时和信号)。
    使用Reactor模型,必备的几个组件:事件源、Reactor框架、多路复用机制和事件处理程序,先来看看Reactor模型的整体框架,接下来再对每个组件做逐一说明。
    这里写图片描述
    图1. Reactor模型UML框架
    (1)事件源
    linux上的是文件描述符,windows上就是socket或者handle,统称句柄集,程序在指定句柄上注册关心的事件,比如I/O事件。
    (2)Event demultiplexer - 事件多路分发机制
    由操作系统提供的I/O多路复用机制,比如select和epoll。
    程序首先将关心的句柄及事件注册到event demultiplexer上,当有事件到达时,event demultiplexer会发出通知,在已经注册的句柄集中一个或多个句柄的事件已经就绪。程序接受到通知后,就可以在非阻塞的情况下对事件进行处理了。对应到libevent中依然是select/poll/epoll等,大师libevent使用结构体eventop进行了分装,以统一的接口来支持这些I/O多路复用机制,达到了对外隐藏底层系统机制的目的。
    (3)Reactor - 反应器
    Reactor是事件管理的接口,内部使用event demultiplexer注册,注销事件,并运行事件循环,当有事件进入“就绪”状态时,调用注册事件回掉函数处理事件。对应到libevent中,即使event_base结构体。
    (4)Event Handle - 事件处理程序
    事件处理程序提供了一组接口,每个接口对应了一种类型的事件,供reactor在相应的事件发生时调用,执行相应的事件处理,通常会绑定一个有效的句柄。
    对应到libevent中就是event结构体。
    结合上面所说,使用一个libevent,请看下列代码:
static void OnAccept(int fd, shor event, void *arg)
{
    /*program code*/
}
int main()
{
    struct event ev;
    /*.......
        .....
        ......*/
    event_init(); //建立event_base相当于Reactor
    event_set(&ev, iSockfd, EV_READ|EV_PERSIST, onAccept, NULL); //设置事件,相当于实例化一个Event handler
    event_add(&ev, NULL); //相当于向reactor注册事件
    event_dispatch(); // 内部调用循环,相当于reactor中的handle_events()方法
    /*......*/
    return 0;
}

简单使用就是下面几点:
· 获取待监听的内容的fd;
· 创建一个event_base;
· 创建一个event,指定待监听的fd,待监听事件的类型,以及事件放生时的回调函数及传给回调函数的参数;
· 将event添加到event_base的事件管理器中;
· 开启event_base的事件处理循环;
· 当事件发生的时候,调用前面设置的回调函数。

阅读更多

没有更多推荐了,返回首页