libevent笔记

1.文档链接

Libevent Reference
Libevent深入浅出

2.安装

# 查询libevent库
sudo apt-cache search libevent
# 安装相关库
sudo apt-get install libevent-2.1-7 libevent-dev
# 查询是否安装成功
apt list --installed|grep libevent

在这里插入图片描述

3.测试

#include <stdio.h>
#include <time.h>

#include <event.h>

struct event ev;
struct timeval tv;
time_t now;

void time_cb(int fd, short event, void *argc)
{
    time(&now);
    printf("timer wakeup:%ld\n", now);
    event_add(&ev, &tv);
}

int main(void)
{
    struct event_base *base = event_init(); /* 1.初始化libevent库,初始化一个Reactor实例 */

    tv.tv_sec = 3;
    tv.tv_usec = 0;

    evtimer_set(&ev, time_cb, NULL); /* 2.初始化时间event, 设置回调函数和关注的事件 */
    event_base_set(base, &ev);       /* 3.设置event从属的event_base */
    event_add(&ev, &tv);             /* 4.添加事件, Reactor::register_handler() */

    printf("start event loop1...\n");
    event_base_dispatch(base); /* 5.开启事件循环,等待就绪事件并执行事件处理 */

    return 0;
}

在这里插入图片描述

4. Event

4.1 event结构体

struct event { 
	TAILQ_ENTRY (event) ev_next; 
	TAILQ_ENTRY (event) ev_active_next; 
	TAILQ_ENTRY (event) ev_signal_next; 
	unsigned int min_heap_idx; /* for managing timeouts */ 
	struct event_base *ev_base; 
	int ev_fd; 
	short ev_events;  // 事件类型
	short ev_ncalls; 
	short *ev_pncalls; /* Allows deletes in callback */ 
	struct timeval ev_timeout; 
	int ev_pri; /* smaller numbers are higher priority */ 
	void (*ev_callback)(int, short, void *arg); 
	void *ev_arg; 
	int ev_res; /* result passed to event callback,当前激活事件的类型 */ 
	int ev_flags; // 用于标记event信息的字段,表明其当前的状态
};

4.2 libevent中定义的事件类型:

// ev_events
#define EV_TIMEOUT 0x01 // 定时事件
#define EV_READ 0x02   // I/O事件
#define EV_WRITE 0x04  // I/O事件
#define EV_SIGNAL 0x08  // 信号
#define EV_PERSIST 0x10 /* 永久事件 Persistant event */

// eb_flags
#define EVLIST_TIMEOUT 0x01 // event在time堆中 
#define EVLIST_INSERTED 0x02 // event在已注册事件链表中 
#define EVLIST_SIGNAL 0x04 // 未见使用 
#define EVLIST_ACTIVE 0x08 // event在激活链表中 
#define EVLIST_INTERNAL 0x10 // 内部使用标记 
#define EVLIST_INIT 0x80 // event 已被初始化

在这里插入图片描述
4.3 事件设置的接口函数

/* 1.设置事件 ev 绑定的文件描述符或者信号,对于定时事件,设为-1 即可;
2.设置事件类型,比如 EV_READ|EV_PERSIST, EV_WRITE, EV_SIGNAL 等;
3.设置事件的回调函数以及参数 arg;
4.初始化其它字段,比如缺省的 event_base 和优先级 */
void event_set(struct event *ev, int fd, short events, 
    			void (*callback)(int, short, void *), void *arg) 
 
/* 设置 event ev 将要注册到的 event_base; 
libevent 有一个全局 event_base 指针 current_base,默认情况下事件 ev
将被注册到 current_base 上,使用该函数可以指定不同的 event_base; 
如果一个进程中存在多个 libevent 实例,则必须要调用该函数为 event 设
置不同的 event_base;*/
int event_base_set(struct event_base *base, struct event *ev)

/* 设置event ev的优先级,注意的一点:当ev正处于就绪状态
时,不能设置,返回-1。*/
int event_priority_set(struct event *ev, int pri)

5.事件处理框架

5.1 event_base

// event-internal.h 
struct event_base { 
	const struct eventop *evsel;  // 类, I/O demultiplex机制统一封装的eventop结构
	void *evbase;  // 实例对象
	int event_count; /* counts number of total events */ 
	int event_count_active; /* counts number of active events */ 
	int event_gotterm; /* Set to terminate loop */ 
	int event_break; /* Set to terminate loop immediately */ 
	/* active event management */ 
	struct event_list **activequeues; 
	int nactivequeues; 
	/* signal handling info */ 
	struct evsignal_info sig; 
	struct event_list eventqueue; 
	struct timeval event_tv; 
	struct min_heap timeheap; 
	struct timeval tv_cache; 
};


struct eventop { 
const char *name; 
void *(*init)(struct event_base *); // 初始化 
int (*add)(void *, struct event *); // 注册事件 
int (*del)(void *, struct event *); // 删除事件 
int (*dispatch)(struct event_base *, void *, struct timeval *); // 事件分发 
void (*dealloc)(struct event_base *, void *); // 注销,释放资源 
/* set if we need to reinitialize the event base */ 
int need_reinit; 
};

5.2 接口函数

// 创建一个event_base对象
struct event_base *event_init(void);
struct event_base *event_base_new(void);

int event_add(struct event *ev, const struct timeval *timeout); // 注册事件
int event_del(struct event *ev);  // 删除事件
int event_base_loop(struct event_base *base, int loops);  // 事件处理主循环
void event_active(struct event *event, int res, short events); 
void event_process_active(struct event_base *base);

6.集成信号处理

6.1 Signal集成到框架
1.集成策略 —— socket pair
一个socket对,包含两个 socket,一个读 socket,一个写 socket。

int evutil_socketpair(int family, int type, int protocol, evutil_socket_t fd[2])

// Libevent 中 Signal 事件的管理 evsignal.h
struct evsignal_info { 
	struct event ev_signal; 
	int ev_signal_pair[2]; 
	int ev_signal_added; 
	volatile sig_atomic_t evsignal_caught; 
	struct event_list evsigevents[NSIG]; 
	 sig_atomic_t evsigcaught[NSIG]; 
	#ifdef HAVE_SIGACTION 
	struct sigaction **sh_old; 
	#else 
	 ev_sighandler_t **sh_old; 
	#endif 
	int sh_old_max; 
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值