对于linux libevent已经提供了一套锁机制,我们就不用自己在写一些锁相关的回掉函数(用evthread_set_lock_callbacks设置)供libevent使用,
我们在linux上使用锁机制的时候只要使用int evthread_use_pthreads(void) 开启使用多线程机制,那么锁的机制也会自动加入进来
int evthread_use_pthreads(void)
{
//对使用的锁进行初始化,包括使用的锁类型,锁分配释放 上锁解锁方式等
struct evthread_lock_callbacks cbs =
{
EVTHREAD_LOCK_API_VERSION,
EVTHREAD_LOCKTYPE_RECURSIVE,
evthread_posix_lock_alloc,
evthread_posix_lock_free,
evthread_posix_lock,
evthread_posix_unlock
};
//对条件变量的初始化, 包括对条件变量对象的分配释放方式 通知和等待方式
struct evthread_condition_callbacks cond_cbs = {
EVTHREAD_CONDITION_API_VERSION,
evthread_posix_cond_alloc,
evthread_posix_cond_free,
evthread_posix_cond_signal,
evthread_posix_cond_wait
};
/* Set ourselves up to get recursive locks. */
//初始化互斥锁属性对象
if (pthread_mutexattr_init(&attr_recursive))
return -1;
//设置成递归锁 即一个线程可以多次进行上锁
if (pthread_mutexattr_settype(&attr_recursive, PTHREAD_MUTEX_RECURSIVE))
return -1;
//将cbs结构内容保存在全局变量中evthread_lock_fns_ 用于后续锁的操作
//当然如果使用evthread_enable_lock_debuging()开启锁的debug模式,则此处的全局变量就是original_lock_fns_
evthread_set_lock_callbacks(&cbs);
//将cond_cbs结构内容保存到全局变量 evthread_cond_fns_用于后续条件变量的使用
//当然如果使用evthread_enable_lock_debuging()开启锁的debug模式,则此处的全局变量就是original_cond_fns_
evthread_set_condition_callbacks(&cond_cbs);
//将获取线程自身id的方式保存到evthread_id_fn_全局变量 用于后续线程获得自己的id
//对于linux来说此处是pthread_self()
evthread_set_id_callback(evthread_posix_get_id);
return 0;
}
那么接下来我们看下evthread_lock_callbacks结构体如下:
struct evthread_lock_callbacks {
int lock_api_version;//锁api的版本号 一般设置为 EVTHREAD_LOCK_API_VERSION
unsigned supported_locktypes;//锁的类型 EVTHREAD_LOCKTYPE_RECURSIVE递归锁 EVTHREAD_LOCKTYPE_READWRITE读写锁
void *(*alloc)(unsigned locktype);//分配一个锁的对象
void (*free)(void *lock, unsigned locktype);//释放一个锁的对象
int (*lock)(unsigned mode, void *lock); //对锁进行上锁
int (*unlock)(unsigned mode, void *lock); //解锁
};
在evthread_use_pthreads中我们初始化此结构如下
struct evthread_lock_callbacks cbs =
{
EVTHREAD_LOCK_API_VERSION, //首先版本设置为1
EVTHREAD_LOCKTYPE_RECURSIVE, //锁的类型为递归锁 允许一个线程多次访问
evthread_posix_lock_alloc, //锁对象的分配方式 看后面
evthread_posix_lock_free, //锁对象的释放方式 看后面
evthread_posix_lock, //上锁方式 看后面
evthread_posix_unlock //解锁方式 看后面
};
/