zoukankan      html  css  js  c++  java
  • 基于事件的开源网络库—libevent:应用介绍

    一、简介

    因memcached(见上一篇“数据缓存系统-memcached介绍”)使用了libevent作为它对外界事件(磁盘、网络等)的监控,所以对libevent就一同进行了了解、应用。

    按libevent的官网(http://libevent.org/)介绍,libevent是一个监视特定事件,提供回调函数的C++库,它可以监视的事件包括:

    1.      能以文件描述符表示的事件(网络、文件等)

    2.      Signal信号(似乎对Linux平台适用)

    3.      定时事件(timeout)

    目前,libevent支持的平台事件监视函数,包括/dev/poll, kqueue(2), event ports, POSIX select(2), Windowsselect(), poll(2), epoll(4),它可以用于多线程应用,由于隔离了底层调用,上层与底层的更新互不影响,除了对事件的监视,libevent还提供了以下的辅助功能:

    1.      带buffer的网络IO-这个东西是libevent中读取网络的接口。

    2.      简单的DNS,HTTP Sever和RPC框架

    总之,libevent作为网络编程框架,其功能还是比较强大的,官网中有一个采用libevent的应用列表,其中就包括memcached。

    (网络编程采用事件回调的方式,大概是高负荷网络IO应用的主要模式,两个主要的开源Web服务器nginx,lighttpd无一例外的采用事件驱动方式。)

     

    二、版本

    在1.X版,初始化event用的是event_init,它默认的是全局一个event base,这被认为不是线程安全的,所以,2.X以后,结构event base被暴露出来供用户使用,一些1.X的API不再适用了。

    目前libevent的版本是2.0.20,也是本文采用的版本,网上一半以上的文章介绍的都是老版本,是不能在新版本下编译的。不过,libevent还是提供了类似XXX-compat.h这样的include文件,供老版本使用。所以,如果采用老版本,应包含XXX-compat.h这样的头文件。

    Libevent2.0版本中,有一个目录event2,专门指的是2.0版本的。

     

    三、编译

    在linux下,该操作是一个典型编译操作,命令如下:

    [plain] view plaincopy
    1. $ ./configure  
    2. $ make  
    3. $ make verify   # (optional)  
    4. $ sudo make install  
    在windows下,可以用以下命令,前提是需要安装vc(vs)。

    [plain] view plaincopy
    1. nmake –f makefile.nmake  

    编译完毕后,应该有以下三个库:

    • libevent_core:所有核心事件功能和buffer功能,包括event_base,evbuffer, bufferevent, utility。
    • libevent_extra:提供某些特定协议的功能,包括HTTP, DNS, RPC。
    • Libevent:因历史原因而保留的库,包含以上两个库的内容, 不应再使用,以后可能消失。

    因此,大部分情况下,我们需要的是libevent_core库。

     

    四、组成和功能

    libevent包含如下部分:

    • evutil

    它抽象了一组辅助功能,并屏蔽了操作系统平台的不同。

    • event 及 event_base

    这是libevent的核心,提供了一组不依赖于操作系统平台的基于事件的非阻塞IO操作。

    • bufferevent

    这个功能基于libevent的事件驱动,提供了非常方便的IO读写,它也可以有多个后端支持,以充分利用操作系统的功能,例如Windows的IOCP API。

    • evbuffer

    这个模块是bufferevent的基础,提供了高效的读写方法。

    • evhttp

    一个简单的HTTP client/server实现。

    • evdns

    一个简单的DNS client/server实现。

    • evrpc

    一个简单的RPC实现。

    五、基本应用框架

    一个典型的libevent的应用大致需要如下步骤:

    (环境设置)-> (创建event_base) -> (创建event,将此event加入到event_base中) -> (设置event各种属性,事件等) ->(将event加入事件列表 addevent) ->(开始事件监视循环、分发dispatch)。

    监视事件发生后,事件处理函数可以只被调用一次或总被调用。

    • 只调用一次:事件处理函数被调用后,即从事件队列中删除,需要在事件处理函数中再次加入事件,才能在下次事件发生时被调用;
    • 总被调用:设置为EV_PERSIST,只加入一次,处理函数总被调用,除非采用event_remove显式地删除。

    如果想退出事件监视循环,可调用event_base_loopexit,此时,event_base_dispatch会退出。

    libevent中提供了需要辅助函数,例如listener.h中对listen,bind等的封装,http.h中对许多http应用的封装等,可以使用这些函数,读写网络时,似乎只能使用bufferevent中的东西。

    目前的设计中,如果是多线程,建议一个线程一个event_base,互不影响,如果一个event_base需要多个线程共享,则需要加锁。


    六、其他考虑

    作为研究,到上一节的介绍就够啦,但正式应用libevent到你的商业系统,还需要考虑如下问题,

    • 日志

    Libevent可以记录错误信息以及调试信息,缺省将其输出到stderr,但嵌入到应用系统后,一般采用应用系统的日志系统,此时,可以修改libevent的日志记录方式,调用event_set_log_callback,需要注意的是自己的日志记录函数不要使用libevent的函数,否则有可能发生难以预料的结果(循环调用)。

    • 错误退出

    如果libevent发生不可恢复的错误(无论是你的事件代码还是它的代码),将调用exit或abort退出进程,调用event_set_fatal_callback可以修改这种行为,同样自定义函数不要使用libevent的函数。

    • 内存管理

    Libevent采用C库中的内存管理函数分配和释放内存,调用event_set_mem_functions可以修改这种方式。(一般我们无需修改)

    • 多线程

    如果采用windows平台或linux平台,系统提供了缺省的多线程支持,否则需要自己实现诸如创建线程、加锁、解锁等相关函数,然后通过evthread_set_lock_callbacks、evthread_set_id_callback告诉libevent。(看样子想完全跨平台还需自己努力了)

    • 调试

    Libevent可以设置为调试状态,调用event_enable_debug_mode,当然仅在开发时使用。

  • 相关阅读:
    jsp实现文件上传——douploadFile.jsp
    jsp实现文件上传——douploadFile.jsp
    jsp实现文件上传——douploadFile.jsp
    JSP实现文件上传——uploadFile.jsp
    JSP实现文件上传——uploadFile.jsp
    JSP实现文件上传——uploadFile.jsp
    JSP的JNDI简单编写
    JSP的JNDI简单编写
    JSP的JNDI简单编写
    服务降级
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13318288.html
Copyright © 2011-2022 走看看