简介
获取libevent的版本号字符串
/**
Get the Libevent version.
Note that this will give you the version of the library that you're
currently linked against, not the version of the headers that you've
compiled against.
@return a string containing the version number of Libevent
*/
EVENT2_EXPORT_SYMBOL
const char *event_get_version(void);
event_dispatch
/**
Loop to process events.
Like event_base_dispatch(), but uses the "current" base.
@deprecated This function is deprecated because it is easily confused by
multiple calls to event_init(), and because it is not safe for
multithreaded use. The replacement is event_base_dispatch().
@see event_base_dispatch(), event_init()
*/
EVENT2_EXPORT_SYMBOL
int event_dispatch(void);
event_base_dispatch
/**
Event dispatching loop
This loop will run the event base until either there are no more pending or
active, or until something calls event_base_loopbreak() or
event_base_loopexit().
@param base the event_base structure returned by event_base_new() or
event_base_new_with_config()
@return 0 if successful, -1 if an error occurred, or 1 if we exited because
no events were pending or active.
@see event_base_loop()
*/
EVENT2_EXPORT_SYMBOL
int event_base_dispatch(struct event_base *);
函数定义
int
event_base_dispatch(struct event_base *event_base)
{
return (event_base_loop(event_base, 0));
}
获取集合中的事件数event_base_get_num_events
int
event_base_get_num_events(struct event_base *base, unsigned int type)
参数:
base:集合
type: 可取值,如下三个宏
/** @name event type flag Flags to pass to event_base_get_num_events() to specify the kinds of events we want to aggregate counts for */ /**@{*/ /** count the number of active events, which have been triggered.*/ #define EVENT_BASE_COUNT_ACTIVE 1U /** count the number of virtual events, which is used to represent an internal * condition, other than a pending event, that keeps the loop from exiting. */ #define EVENT_BASE_COUNT_VIRTUAL 2U /** count the number of events which have been added to event base, including * internal events. */ #define EVENT_BASE_COUNT_ADDED 4U /**@}*/
返回值:获取指定类型的集合数
int
event_base_get_num_events(struct event_base *base, unsigned int type)
{
int r = 0;
EVBASE_ACQUIRE_LOCK(base, th_base_lock);
if (type & EVENT_BASE_COUNT_ACTIVE)
r += base->event_count_active;
if (type & EVENT_BASE_COUNT_VIRTUAL)
r += base->virtual_event_count;
if (type & EVENT_BASE_COUNT_ADDED)
r += base->event_count;
EVBASE_RELEASE_LOCK(base, th_base_lock);
return r;
}
evtimer_set宏
这是一个宏
#define evtimer_set(ev, cb, arg) event_set((ev), -1, 0, (cb), (arg))
void
event_set(struct event *ev, evutil_socket_t fd, short events,
void (*callback)(evutil_socket_t, short, void *), void *arg)
{
int r;
r = event_assign(ev, current_base, fd, events, callback, arg);
EVUTIL_ASSERT(r == 0);
}
测试代码一:
#include <sys/types.h>
#include <event2/event-config.h>
#include <event2/listener.h>
#include <stdio.h>
#include <event.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define _DEBUG_INFO
#ifdef _DEBUG_INFO
#define DEBUG_INFO(format, ...) printf("%s:%d $$ "format"\n",__func__,__LINE__ , ##__VA_ARGS__)
#else
#define DEBUG_INFO(format, ...)
#endif
struct private_timer_data{
struct event ev;
struct timeval tv;
};
void timer_1s_cb(int fd,short event,void *arg){
struct private_timer_data * ptd = (struct private_timer_data*)arg;
DEBUG_INFO("fd = %d, event = %d",fd,(int)event);
free(ptd);
}
void timer_5s_cb(int fd,short event,void *arg){
struct private_timer_data * ptd = (struct private_timer_data*)arg;
DEBUG_INFO("fd = %d, event = %d",fd,(int)event);
free(ptd);
}
void* base_01_thread(void *arg){
struct event_base *base = (struct event_base *)arg;
while(event_base_get_num_events(base,EVENT_BASE_COUNT_ADDED) == 0){
sleep(1);
}
DEBUG_INFO("%d %d %d",
event_base_get_num_events(base,EVENT_BASE_COUNT_ADDED),
event_base_get_num_events(base,EVENT_BASE_COUNT_VIRTUAL),
event_base_get_num_events(base,EVENT_BASE_COUNT_ACTIVE));
event_base_dispatch(base);
event_base_free(base);
DEBUG_INFO("集合下班了");
return NULL;
}
int main(int argc, char *argv[]){
struct event_base *base;
DEBUG_INFO("libevent version = %s",event_get_version());
base = event_base_new();
if(base == NULL){
DEBUG_INFO("event_base_new error");
}
;
pthread_t __attribute__((unused)) t1;
pthread_t __attribute__((unused)) t2;
if(pthread_create(&t1,NULL,base_01_thread,base) < 0){
perror((const char*)"pthread_create");
exit(-1);
}
struct private_timer_data * ptd;
//设置1秒定时器
ptd = (struct private_timer_data*)malloc(sizeof(struct private_timer_data));
ptd->tv.tv_sec = 1;
ptd->tv.tv_usec = 0;
evtimer_set(&ptd->ev,timer_1s_cb,ptd);
event_base_set(base,&ptd->ev);
event_add(&ptd->ev,&ptd->tv);
//设置5秒定时器
ptd = (struct private_timer_data*)malloc(sizeof(struct private_timer_data));
ptd->tv.tv_sec = 5;
ptd->tv.tv_usec = 0;
evtimer_set(&ptd->ev,timer_5s_cb,ptd);
event_base_set(base,&ptd->ev);
event_add(&ptd->ev,&ptd->tv);
DEBUG_INFO("%d %d %d",
event_base_get_num_events(base,EVENT_BASE_COUNT_ADDED),
event_base_get_num_events(base,EVENT_BASE_COUNT_VIRTUAL),
event_base_get_num_events(base,EVENT_BASE_COUNT_ACTIVE));
while(event_base_get_num_events(base,EVENT_BASE_COUNT_ADDED) > 0){
sleep(1);
}
sleep(1);
DEBUG_INFO("byebye");
return 0;
}
执行结果:
实验解析:
这个定时器的缺点是一次性的,如果想让定时器多次触发,有两个方法,一个是在定时器函数中使用event_add。第二个是使用选项宏EV_PERSIST,下面重点使用EV_PERSIST选项+event_set函数实现定时器。
测试代码二
#include <sys/types.h>
#include <event2/event-config.h>
#include <event2/listener.h>
#include <stdio.h>
#include <event.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define _DEBUG_INFO
#ifdef _DEBUG_INFO
#define DEBUG_INFO(format, ...) printf("%s:%d $$ "format"\n",__func__,__LINE__ , ##__VA_ARGS__)
#else
#define DEBUG_INFO(format, ...)
#endif
struct private_timer_data{
struct event ev;
struct timeval tv;
};
void timer_1s_cb(int fd,short event,void *arg){
struct private_timer_data * ptd = (struct private_timer_data*)arg;
DEBUG_INFO("fd = %d, event = %d",fd,(int)event);
DEBUG_INFO("event = %d,0x%02x %s %s %s %s",event,event,
((event & EV_TIMEOUT)?"EV_TIMEOUT":""),
((event & EV_READ)?"EV_READ":""),
((event & EV_WRITE)?"EV_WRITE":""),
((event & EV_PERSIST)?"EV_PERSIST":"")
);
static int count = 0;
count++;
if(count >= 2){
event_del(&ptd->ev);
free(ptd);
}
}
void timer_5s_cb(int fd,short event,void *arg){
struct private_timer_data * ptd = (struct private_timer_data*)arg;
DEBUG_INFO("fd = %d, event = %d",fd,(int)event);
DEBUG_INFO("event = %d,0x%02x %s %s %s %s",event,event,
((event & EV_TIMEOUT)?"EV_TIMEOUT":""),
((event & EV_READ)?"EV_READ":""),
((event & EV_WRITE)?"EV_WRITE":""),
((event & EV_PERSIST)?"EV_PERSIST":"")
);
static int count = 0;
count++;
if(count >= 2){
event_del(&ptd->ev);
free(ptd);
}
}
void* base_01_thread(void *arg){
struct event_base *base = (struct event_base *)arg;
while(event_base_get_num_events(base,EVENT_BASE_COUNT_ADDED) == 0){
sleep(1);
}
DEBUG_INFO("%d %d %d",
event_base_get_num_events(base,EVENT_BASE_COUNT_ADDED),
event_base_get_num_events(base,EVENT_BASE_COUNT_VIRTUAL),
event_base_get_num_events(base,EVENT_BASE_COUNT_ACTIVE));
event_base_dispatch(base);
event_base_free(base);
DEBUG_INFO("集合下班了");
return NULL;
}
int main(int argc, char *argv[]){
struct event_base *base;
DEBUG_INFO("libevent version = %s",event_get_version());
base = event_base_new();
if(base == NULL){
DEBUG_INFO("event_base_new error");
}
;
pthread_t __attribute__((unused)) t1;
pthread_t __attribute__((unused)) t2;
if(pthread_create(&t1,NULL,base_01_thread,base) < 0){
perror((const char*)"pthread_create");
exit(-1);
}
struct private_timer_data * ptd;
//设置1秒定时器
ptd = (struct private_timer_data*)malloc(sizeof(struct private_timer_data));
ptd->tv.tv_sec = 1;
ptd->tv.tv_usec = 0;
// evtimer_set(&ptd->ev,timer_1s_cb,ptd);
event_set((&ptd->ev), -1, EV_PERSIST, (timer_1s_cb), (ptd));
event_base_set(base,&ptd->ev);
event_add(&ptd->ev,&ptd->tv);
//设置5秒定时器
ptd = (struct private_timer_data*)malloc(sizeof(struct private_timer_data));
ptd->tv.tv_sec = 5;
ptd->tv.tv_usec = 0;
// evtimer_set(&ptd->ev,timer_5s_cb,ptd);
event_set((&ptd->ev), -1, EV_PERSIST, (timer_5s_cb), (ptd));
event_base_set(base,&ptd->ev);
event_add(&ptd->ev,&ptd->tv);
DEBUG_INFO("%d %d %d",
event_base_get_num_events(base,EVENT_BASE_COUNT_ADDED),
event_base_get_num_events(base,EVENT_BASE_COUNT_VIRTUAL),
event_base_get_num_events(base,EVENT_BASE_COUNT_ACTIVE));
while(event_base_get_num_events(base,EVENT_BASE_COUNT_ADDED) > 0){
sleep(1);
}
sleep(1);
DEBUG_INFO("byebye");
return 0;
}
执行结果:
实验解析:
在定时器处理函数中使用了计数器,计数两次,定时器事件从集合中删除。