您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 质量控制/管理 > libevent参考手册(中文版)
原创:整理:前言翻译自:~nickm/libevent-book/Ref0_meta.html1111....从一万英尺外看LibeventLibeventLibeventLibeventLibevent是用于编写高速可移植非阻塞IO应用的库,其设计目标是:�可移植性:使用libevent编写的程序应该可以在libevent支持的所有平台上工作。即使没有好的方式进行非阻塞IO,libevent也应该支持一般的方式,让程序可以在受限的环境中运行。�速度:libevent尝试使用每个平台上最高速的非阻塞IO实现,并且不引入太多的额外开销。�可扩展性:libevent被设计为程序即使需要上万个活动套接字的时候也可以良好工作。�方便:无论何时,最自然的使用libevent编写程序的方式应该是稳定的、可移植的。libevent由下列组件构成:�evutil:用于抽象不同平台网络实现差异的通用功能。�event和event_base:libevent的核心,为各种平台特定的、基于事件的非阻塞IO后端提供抽象API,让程序可以知道套接字何时已经准备好,可以读或者写,并且处理基本的超时功能,检测OS信号。�bufferevent:为libevent基于事件的核心提供使用更方便的封装。除了通知程序套接字已经准备好读写之外,还让程序可以请求缓冲的读写操作,可以知道何时IO已经真正发生。(bufferevent接口有多个后端,可以采用系统能够提供的更快的非阻塞IO方式,如Windows中的IOCP。)�evbuffer:在bufferevent层之下实现了缓冲功能,并且提供了方便有效的访问函数。�evhttp:一个简单的HTTP客户端/服务器实现。�evdns:一个简单的DNS客户端/服务器实现。�evrpc:一个简单的RPC实现。2222....库创建libevent时,默认安装下列库:�ibevent_core:所有核心的事件和缓冲功能,包含了所有的event_base、evbuffer、bufferevent和工具函数。�ibevent_extra:定义了程序可能需要,也可能不需要的协议特定功能,包括HTTP、DNS和RPC。�libevent:这个库因为历史原因而存在,它包含libevent_core和libevent_extra的内容。不应该使用这个库,未来版本的libevent可能去掉这个库。某些平台上可能安装下列库:�libevent_pthreads:添加基于pthread可移植线程库的线程和锁定实现。它独立于libevent_core,这样程序使用libevent时就不需要链接到pthread,除非是以多线程方式使用libevent。�libevent_openssl:这个库为使用bufferevent和OpenSSL进行加密的通信提供支持。它独立于libevent_core,这样程序使用libevent时就不需要链接到OpenSSL,除非是进行加密通信。3333....头文件libevent公用头文件都安装在event2目录中,分为三类:�API头文件:定义libevent公用接口。这类头文件没有特定后缀。�兼容头文件:为已废弃的函数提供兼容的头部包含定义。不应该使用这类头文件,除非是在移植使用较老版本libevent的程序时。�结构头文件:这类头文件以相对不稳定的布局定义各种结构体。这些结构体中的一些是为了提供快速访问而暴露;一些是因为历史原因而暴露。直接依赖这类头文件中的任何结构体都会破坏程序对其他版本libevent的二进制兼容性,有时候是以非常难以调试的方式出现。这类头文件具有后缀“_struct.h”。(还存在不在event2目录中的较老版本libevent的头文件,请参考下节:如果需要使用老版本libevent)4444....如果需要使用老版本libeventlibeventlibeventlibeventlibevent2.0以更合理的、不易出错的方式修正了API。如果可能,编写新程序时应该使用libevent2.0。但是有时候可能需要使用较老的API,例如在升级已存的应用时,或者支持因为某些原因不能安装2.0或者更新版本libevent的环境时。较老版本的libevent头文件较少,也不安装在event2目录中。在2.0以及以后版本的libevent中,老的头文件仍然会作为新头文件的封装而存在。其他关于使用较老版本的提示:�1.4版之前只有一个库libevent,它包含现在分散到libevent_core和libevent_extra中的所有功能。�2.0版之前不支持锁定:只有确定不同时在多个线程中使用同一个结构体时,libevent才是线程安全的。下面的节还将讨论特定代码区域可能遇到的已经废弃的API。5555....关于版本状态的提示1.4.7及以前版本应该被认为是完全废弃的。1.3之前的版本应该被认为是充满bug的。(此外,不要向libevent维护者发送任何关于1.4.x或者更早版本的新特征,这些版本被认为是稳定的发布版本。如果在1.3x或者更早版本中发现bug,在报告之前请确定在最新的稳定发布版本中问题仍然存在:后续发布可能已经解决了问题。)第一章:设置libeventlibeventlibeventlibevent翻译自:~nickm/libevent-book/Ref1_libsetup.htmllibevent有一些被整个进程共享的、影响整个库的全局设置。必须在调用libevent库的任何其他部分之前修改这些设置,否则,libevent会进入不一致的状态。1111....LibeventLibeventLibeventLibevent中的日志消息libevent可以记录内部错误和警告。如果编译进日志支持,还会记录调试信息。默认配置下这些信息被写到stderr。通过提供定制的日志函数可以覆盖默认行为。接口要覆盖libevent的日志行为,编写匹配event_log_cb签名的定制函数,将其作为参数传递给event_set_log_callback()。随后libevent在日志信息的时候,将会把信息传递给你提供的函数。再次调用event_set_log_callback(),传递参数NULL,就可以恢复默认行为。示例……省略示例代码……注意在用户提供的event_log_cb回调函数中调用libevent函数是不安全的。比如说,如果试图编写一个使用bufferevent将警告信息发送给某个套接字的日志回调函数,可能会遇到奇怪而难以诊断的bug。未来版本libevent的某些函数可能会移除这个限制。这个函数在event2/event.h中声明,在libevent1.0c版本中首次出现。2222....处理致命错误libevent在检测到不可恢复的内部错误时的默认行为是调用exit()或者abort(),退出正在运行的进程。这类错误通常意味着某处有bug:要么在你的代码中,要么在libevent中。如果希望更优雅地处理致命错误,可以为libevent提供在退出时应该调用的函数,覆盖默认行为。接口要使用这些函数,首先定义libevent在遇到致命错误时应该调用的函数,将其传递给event_set_fatal_callback()。随后libevent在遇到致命错误时将调用你提供的函数。你的函数不应该将控制返回到libevent:这样做可能导致不确定的行为。为了避免崩溃,libevent还是会退出。你的函数被不应该调用其它libevent函数。这些函数声明在event2/event.h中,在libevent2.0.3-alpha版本中首次出现。3333....内存管理默认情况下,libevent使用C库的内存管理函数在堆上分配内存。通过提供malloc、realloc和free的替代函数,可以让libevent使用其他的内存管理器。希望libevent使用一个更高效的分配器时;或者希望libevent使用一个工具分配器,以便检查内存泄漏时,可能需要这样做。接口这里有个替换libevent分配器函数的示例,它可以计算已经分配的字节数。实际应用中可能需要添加锁,以避免运行在多个线程中时发生错误。示例……省略示例代码……注意�替换内存管理函数影响libevent随后的所有分配、调整大小和释放内存操作。所以,必须保证在调用任何其他libevent函数之前进行替换。否则,libevent可能用你的free函数释放用C库的malloc分配的内存。�你的malloc和realloc函数返回的内存块应该具有和C库返回的内存块一样的地址对齐。�你的realloc函数应该正确处理realloc(NULL,sz)(也就是当作malloc(sz)处理)�你的realloc函数应该正确处理realloc(ptr,0)(也就是当作free(ptr)处理)�你的free函数不必处理free(NULL)�你的malloc函数不必处理malloc(0)�如果在多个线程中使用libevent,替代的内存管理函数需要是线程安全的。�libevent将使用这些函数分配返回给你的内存。所以,如果要释放由libevent函数分配和返回的内存,而你已经替换malloc和realloc函数,那么应该使用替代的free函数。event_set_mem_functions函数声明在event2/event.h中,在libevent2.0.1-alpha版本中首次出现。可以在禁止event_set_mem_functions函数的配置下编译libevent。这时候使用event_set_mem_functions将不会编译或者链接。在2.0.2-alpha及以后版本中,可以通过检查是否定义了EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED宏来确定event_set_mem_functions函数是否存在。4444....锁和线程编写多线程程序的时候,在多个线程中同时访问同样的数据并不总是安全的。libevent的结构体在多线程下通常有三种工作方式:�某些结构体内在地是单线程的:同时在多个线程中使用它们总是不安全的。�某些结构体具有可选的锁:可以告知libevent是否需要在多个线程中使用每个对象。�某些结构体总是锁定的:如果libevent在支持锁的配置下运行,在多个线程中使用它们总是安全的。为获取锁,在调用分配需要在多个线程间共享的结构体的libevent函数之前,必须告知libevent使用哪个锁函数。如果使用pthreads库,或者使用Windows本地线程代码,那么你是幸运的:已经有设置libevent使用正确的pthreads或者Windows函数的预定义函数。接口这些函数在成功时都返回0,失败时返回-1。如果使用不同的线程库,则需要一些额外的工作,必须使用你的线程库来定义函数去实现:�锁�锁定�解锁�分配锁�析构锁�条件变量�创建条件变量�析构条件变量�等待条件变量�触发/广播某条件变量�线程�线程ID检测使用evthread_set_lock_callbacks和evthread_set_id_callback接口告知libevent这些函数。接口evthread_lock_callbacks结构体描述的锁回调函数及其能力。对于上述版本,lock_api_version字段必须设置为EVTHREAD_LOCK_API_VERSION。必须设置supported_locktypes字段为EVTHREAD_LOCKTYPE_*常量的组合以描述支持的锁类型(在2.0.4-alpha版本中,EVTHREAD_LOCK_RECURSIVE是必须的,EVTHREAD_LOCK_READWRITE则
本文标题:libevent参考手册(中文版)
链接地址:https://www.777doc.com/doc-4815695 .html