libevent使用(一)-----基础配置

Libevent中的日志消息

Ibevent会记录内部发生的错误和警告,当然,我们也可以自己实现日志函数覆盖框架原本提供的

typedefvoid (*event_log_cb)(intseverity, constchar *msg);
void event_set_log_callback(event_log_cb cb);

可见,我们可以通过给event_set_log_callback 函数传递参数的形式使框架调用我们的函数。如果想恢复使用默认函数,那么给此函数传递NULL就行

 

 

处理致命错误

Libevent框架处理致命错误的方式一般是调用 exit 或是abort ,这种错误意味着程序中存在着bug,无论是在你写的程序还是libevent里。

         因此,如果我们希望程序可以更明智的处理发生的这类问题,我们可以自己提供处理这种错误的函数:

typedefvoid (*event_fatal_cb)(int err);
void event_set_fatal_callback(event_fatal_cb cb);

         既然发生了这类错误,且调用自己的函数去处理了,我们就不能再把控制权转给libevent了,因为这回导致libevent不确定的行为。

 

 

内存管理

         Libevent使用的是C中的malloc, realloc,free

         如果你有更好的,也可以替代

 

void event_set_mem_functions(void *(*malloc_fn)(size_t sz),
                             void *(*realloc_fn)(void *ptr, size_t sz),
                             void (*free_fn)(void *ptr));

书上给了一个替换了例子,例子里替换这三个函数主要是为了计算当前已经申请了多少空间

 

#include <event2/event.h>
#include <sys/types.h>
#include <stdlib.h>
 
/* This union's purpose is to be as big as the largest of all the
 * types it contains. */
union alignment {
    size_t sz;
    void *ptr;
    double dbl;
};
/* We need to make sure that everything we return is on the right
   alignment to hold anything, including a double. */
#define ALIGNMENT sizeof(union alignment)
 
/* We need to do this cast-to-char* trick on our pointers to adjust
   them; doing arithmetic on a void* is not standard. */
//void类型指针不适合作计算; 指针做加法是往后移; 减法往前挪
#define OUTPTR(ptr) (((char*)ptr)+ALIGNMENT)
#define INPTR(ptr) (((char*)ptr)-ALIGNMENT)
 
static size_t total_allocated = 0;
staticvoid *replacement_malloc(size_t sz)
{
    //故意躲分配一个size_t的空间,用于记录本段内存的大小
    void *chunk = malloc(sz + ALIGNMENT);
    if (!chunk) return chunk;
total_allocated += sz;
//这里记录下本段空间的大小
*(size_t*)chunk = sz;
//这里返回的是客户要用的空间,而本段空间之前的size_t大小的空间就一直留着以后用
    return OUTPTR(chunk);
}
staticvoid *replacement_realloc(void *ptr, size_t sz)
{
size_t old_size = 0;
//如果本段空间是本就存在的,那么先得到它的大小
    if (ptr) {
        ptr = INPTR(ptr);
        old_size = *(size_t*)ptr;
}
//重新申请的空间也要多申请,用于记录空间大小
    ptr = realloc(ptr, sz + ALIGNMENT);
    if (!ptr)
        return NULL;
*(size_t*)ptr = sz;
//最后总大小就是total减去原本ptr指向空间大小,加上现在重新申请的空间的大小
    total_allocated = total_allocated - old_size + sz;
    return OUTPTR(ptr);
}
staticvoid replacement_free(void *ptr)
{
      //因为之前申请都是申请客户需要的大小加上一个size_t大小的内存,所以现在free也要都free掉,ptr往前挪之后 *(size_t*)ptr就注明了本段空间的大小
    ptr = INPTR(ptr);
    total_allocated -= *(size_t*)ptr;
    free(ptr);
}
void start_counting_bytes(void)
{
    event_set_mem_functions(replacement_malloc,
                            replacement_realloc,
                            replacement_free);
}


 

要注意的是:

1、  内存分配是个普遍需求,一定要在调用任何其他libevent函数之前就声明好我们自己的空间配置函数

2、  Your realloc function needs to handle realloc(NULL, sz) correctly(that is, by treating it as malloc(sz))

3、  要配套,别只替换三个中的某(两)个函数

 

 

锁和线程

要注意的是:

1、  某些结构体总是只能在单线程操作的,多线程中处理总是不安全的

2、  某些结构体可选锁,可告知libevent是否需要在多线程中使用每个对象

3、  某些结构体总是锁定的,如果libevent在支持锁的配置下运行,总是安全的

 

如果使用pthread 或windows下的锁,那么是提供的:

 
#ifdef WIN32
int evthread_use_windows_threads(void);
#define EVTHREAD_USE_WINDOWS_THREADS_IMPLEMENTED
#endif
#ifdef _EVENT_HAVE_PTHREADS
int evthread_use_pthreads(void);
#define EVTHREAD_USE_PTHREADS_IMPLEMENTED
#endif

否则提供自己的线程实现。这里不再继续

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值