`
lobin
  • 浏览: 417649 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

libevent

 
阅读更多

 

libevent

在讲之前,先介绍struct event_base结构,以及几个内部全局变量,包括内部全局的struct event_base实例。

 

在介绍struct event_base结构之前,还得先介绍几个结构和定义

 

尾队列

尾队列定义

尾队列包括一个next指向下一个元素,这通过是通过一个指针来实现,还有一个prev指向前一个元素的next成员,因为next是通过指针来实现,所以prev通过一个双指针(指针的指针)来实现。如上,tqe_next是一个struct type结构体的指针,它指向下一个truct type结构体元素,tqe_prev是一个struct type结构体的指针的指针,它指向前一个truct type结构体元素的next成员,因为next是一个指针,tqe_prev指向它就应该是一个双指针(指针的指针)。

 

下面定义了尾队列的主要结构以及next,prev的指向是怎么定义的。

 

#define TAILQ_ENTRY(type)						\
struct {								\
	struct type *tqe_next;	/* next element */			\
	struct type **tqe_prev;	/* address of previous next element */	\
}
宏TAILQ_ENTRY定义了一个模板,包括尾队列的主要结构以及next,prev的指向是怎么定义的。

 

 

/*
 * Tail queue definitions.
 */
#define TAILQ_HEAD(name, type)						\
struct name {								\
	struct type *tqh_first;	/* first element */			\
	struct type **tqh_last;	/* addr of last next element */		\
}

宏TAILQ_HEAD定义了一个结构体模板,包括尾队列的第一个元素和最后一个元素的前一个元素的next成员。通过TAILQ_ENTRY,TAILQ_HEAD这两个宏可以定义自己的尾队列结构。

 

如我们想定义一个尾队列:

struct el 

{

  TAILQ_ENTRY(el) el_next;

  // members of struct el

  ...

  ...

}

 

TAILQ_HEAD(tq, el);

 

实际完整结构是这样的:

struct el 

{

  struct

  {

    struct el *tqe_next; /* next element */

    struct el **tqe_prev; /* address of previous next element */

  } el_next;

  // members of struct el

  ...

  ...

}

 

struct tq 

{

  struct el *tqh_first; /* first element */

  struct el **tqh_last; /* addr of last next element */

}

 

 

尾队列初始化

 

/*
 * Tail queue functions.
 */
#define	TAILQ_INIT(head) do {						\
	(head)->tqh_first = NULL;					\
	(head)->tqh_last = &(head)->tqh_first;				\
} while (0)

 

 

 

#define TAILQ_HEAD_INITIALIZER(head)					\
	{ NULL, &(head).tqh_first }
 

 

 

struct eventop

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;
};

 

ev_sighandler_t

这是个指针函数定义

 

typedef void (*ev_sighandler_t)(int);

 

struct evsignal_info

 

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;
};
 

 

 

struct event_list

这个是一个尾队列,结构定义如下:

TAILQ_HEAD (event_list, event);
struct event_list {
	struct event *tqh_first;	/* first element */
	struct event **tqh_last;	/* addr of last next element */
}

 

struct evkeyvalq

这个是一个尾队列,结构定义如下:

TAILQ_HEAD (evkeyvalq, evkeyval);

 

struct evkeyvalq {
	struct evkeyval *tqh_first;	/* first element */
	struct evkeyval **tqh_last;	/* addr of last next element */
}

 

struct min_heap

typedef struct min_heap
{
    struct event** p;
    unsigned n, a;
} min_heap_t;

这是个heap结构

p

堆顶

n

堆中元素的个数

a

堆的容量

 

struct event_base

struct event_base {
	const struct eventop *evsel;
	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 event_base设计为内部结构,在外面是不能直接访问到struct event_base。包括libevent内部维护的全局的struct event_base实例,在外面也不能直接访问到这个实例。

 

evsel

 

evbase

 

event_count

 

event_count_active

 

event_gotterm

 

event_break

 

activequeues

 

nactivequeues

 

sig

 

eventqueue

 

event_tv

 

timeheap

这是个struct min_heap类型的成员变量,

 

tv_cache

 

 

 

几个内部全局变量,包括内部全局的struct event_base实例

/* Global state */
struct event_base *current_base = NULL;
extern struct event_base *evsignal_base;
static int use_monotonic;

/* Handle signals - This is a deprecated interface */
int (*event_sigcb)(void);		/* Signal callback when gotsig is set */
volatile sig_atomic_t event_gotsig;	/* Set in signal handler */

 

内部全局的struct event_base实例

struct event_base *current_base = NULL;

 

用于信号的内部全局的struct event_base实例

extern struct event_base *evsignal_base;

 

是否支持MONOTONIC时间

static int use_monotonic;

 

信号处理回调

int (*event_sigcb)(void);

 

volatile sig_atomic_t event_gotsig;

另一个比较重要的内部全局变量就是

static const struct eventop *eventops[]

其初始化是这样的,它将所有可能提供的事件机制的操作都初始化进去了。

/* In order of preference */
static const struct eventop *eventops[] = {
#ifdef HAVE_EVENT_PORTS
	&evportops,
#endif
#ifdef HAVE_WORKING_KQUEUE
	&kqops,
#endif
#ifdef HAVE_EPOLL
	&epollops,
#endif
#ifdef HAVE_DEVPOLL
	&devpollops,
#endif
#ifdef HAVE_POLL
	&pollops,
#endif
#ifdef HAVE_SELECT
	&selectops,
#endif
#ifdef WIN32
	&win32ops,
#endif
	NULL
};

所有可能提供的事件机制的操作都是一个struct eventop结构体类型的变量。

 

#ifdef HAVE_EVENT_PORTS
extern const struct eventop evportops;
#endif
#ifdef HAVE_SELECT
extern const struct eventop selectops;
#endif
#ifdef HAVE_POLL
extern const struct eventop pollops;
#endif
#ifdef HAVE_EPOLL
extern const struct eventop epollops;
#endif
#ifdef HAVE_WORKING_KQUEUE
extern const struct eventop kqops;
#endif
#ifdef HAVE_DEVPOLL
extern const struct eventop devpollops;
#endif
#ifdef WIN32
extern const struct eventop win32ops;
#endif
第1个是端口
第2个是select
第3个是poll
第4个是epoll
第5个是kqueue
第6个是/dev/poll
第7个是windows下提供的事件机制

 

 

针对端口提供的struct eventop结构体类型的变量

其初始化如下:

const struct eventop evportops = {
	"evport",
	evport_init,
	evport_add,
	evport_del,
	evport_dispatch,
	evport_dealloc,
	1 /* need reinit */
};

 

针对kqueue提供的struct eventop结构体类型的变量

其初始化如下:

const struct eventop kqops = {
	"kqueue",
	kq_init,
	kq_add,
	kq_del,
	kq_dispatch,
	kq_dealloc,
	1 /* need reinit */
};

 

针对epoll提供的struct eventop结构体类型的变量

其初始化如下:

const struct eventop epollops = {
	"epoll",
	epoll_init,
	epoll_add,
	epoll_del,
	epoll_dispatch,
	epoll_dealloc,
	1 /* need reinit */
};

 

针对/dev/poll提供的struct eventop结构体类型的变量

其初始化如下:

const struct eventop devpollops = {
	"devpoll",
	devpoll_init,
	devpoll_add,
	devpoll_del,
	devpoll_dispatch,
	devpoll_dealloc,
	1 /* need reinit */
};

 

针对poll提供的struct eventop结构体类型的变量

其初始化如下:

const struct eventop pollops = {
	"poll",
	poll_init,
	poll_add,
	poll_del,
	poll_dispatch,
	poll_dealloc,
    0
};

 

 

针对select提供的struct eventop结构体类型的变量

其初始化如下:

 

const struct eventop selectops = {
	"select",
	select_init,
	select_add,
	select_del,
	select_dispatch,
	select_dealloc,
	0
};
 

 

 

select

 

poll

 

epoll

 

/dev/poll

 

#include <sys/devpoll.h>

 

kqueue

写道
kqueue, kevent -- kernel event notification mechanism
https://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2

 

 

port

写道

 

 

libevent支持的这些事件机制并不是在任何平台上都支持,这些事件机制基本都是平台相关的。如kqueue是UNIX支持的事件机制,port是UNIX Solaris支持的事件机制,linux下通常支持select, poll, epoll这几种事件机制。libevent的优势是提供跨平台的事件机制编程模型。

 

禁用epoll

设置环境变量EVENT_NOEPOLL,只需要设置这个环境变量就行,随便设置什么值。

# export EVENT_NOEPOLL=0

 

禁用poll

设置环境变量EVENT_NOPOLL,只需要设置这个环境变量就行,随便设置什么值。

# export EVENT_NOPOLL=0

 

禁用select

设置环境变量EVENT_NOSELECT,只需要设置这个环境变量就行,随便设置什么值。

# export EVENT_NOSELECT=0

 

如果不支持任何事件机制,或者所有事件机制都被禁用,将报如下错误:

[err] event_base_new: no event mechanism available

 

 

 

 

 

  • 大小: 10.9 KB
分享到:
评论

相关推荐

    libevent参考手册中文版_libevent-2.1.5.pdf

    libevent是一个高性能的事件通知库,主要由Nick Mathewson和Abdul Razzaq开发,用C语言编写。它基于Reactor设计模式,并提供了一个轻量级、跨平台、多线程的事件循环,广泛应用于网络服务器的开发中,能够处理多种I/...

    libevent-vs2017编译

    标题"libevent-vs2017编译"指的是使用Visual Studio 2017在Windows环境下编译开源库Libevent。Libevent是一个事件通知库,广泛用于编写高性能网络服务器,它提供了异步事件处理的能力,允许程序高效地处理大量并发...

    libevent源码深度剖析pdf

    为方便阅读,把blog上的libevent源码深度剖析系列文章整合成一个pdf。

    VS2015编译后的libevent头文件和库文件——基于libevent-2.1.10

    libevent是一个开源的事件通知库,它在C语言中实现,广泛应用于网络编程,尤其是服务器端的高并发处理。它通过提供一个统一的API,使得开发者能够方便地处理各种I/O事件,如网络套接字、信号、定时器等。在本资源中...

    libevent多线程处理

    本文将深入探讨如何在多线程环境中使用Libevent进行事件处理,并分享一个基于Libevent的多线程实现案例。 首先,理解Libevent的核心机制至关重要。Libevent提供了一个事件基础结构,它能够将来自不同来源的事件(如...

    libevent 参考手册中文版及源码解析

    标题"libevent 参考手册中文版及源码解析"表明了本次学习的主题,重点是libevent库,包含了中文参考手册和源码的深度解析。libevent是一个开源的事件通知库,它使开发者能够方便地处理各种网络事件,如TCP、UDP、...

    Libevent2.0.21编译好的库

    Libevent 是一个高度可移植、事件驱动的网络库,它被广泛用于编写高性能的服务器端和客户端应用。这个库提供了一种方式来处理各种输入/输出事件,如网络连接、定时器以及信号,使得开发者可以编写非阻塞的、反应灵敏...

    libevent2.1.7在Linux安装过程

    libevent2.1.7在Linux安装过程 libevent是一个开源的异步I/O库,广泛应用于服务器端编程和网络编程中。安装libevent2.1.7需要遵循特定的步骤,以确保正确安装。下面将详细介绍libevent2.1.7在Linux安装过程。 一...

    运用libevent的缓存示例

    在这个“运用libevent的缓存示例”中,我们将深入探讨如何利用libevent的API来创建和管理一个简单的缓存系统。 首先,让我们了解libevent的核心概念。它基于事件驱动模型,主要通过三种方式处理事件:水平触发...

    libevent 多线程 HTTP post服务器

    "libevent" 标签明确了技术核心,即libevent库,它是一个跨平台的事件通知库,可以处理TCP/UDP套接字、信号、时间事件等多种I/O事件。 "多线程" 标签表明了服务器采用了多线程编程模型,通过线程池或并发线程处理...

    libevent(2.1.8)库及头文件文件

    标题中的"libevent(2.1.8)库及头文件文件"指的是一个开源的事件通知库——Libevent的特定版本,即2.1.8稳定版。这个库提供了异步网络I/O和时间事件处理的能力,广泛应用于服务器端的开发,如HTTP服务器、DNS解析器...

    libevent-2.0.22-stable在windows环境下使用mingw编译

    标题"libevent-2.0.22-stable在windows环境下使用mingw编译"指的是一个关于使用MinGW编译工具在Windows操作系统上构建libevent库的2.0.22稳定版本的过程。libevent是一个开源的、跨平台的事件通知库,它提供了一种...

    基于libevent的tcp server开发环境的完整工程

    **基于libevent的TCP服务器开发环境详解** 在IT行业中,构建高效的网络服务是至关重要的,而libevent是一个轻量级的库,专为处理大量并发连接的网络服务器设计。本项目是一个基于libevent的TCP服务器开发环境的完整...

    libevent-devel-2.0.21-4.el7.x86_64.rpm

    《深入理解libevent-devel及其在CentOS 7中的应用》 libevent是一个开源的、跨平台的库,它提供了一种高效的方式来处理时间驱动和事件驱动的编程。这个库允许程序处理大量的并发连接,而无需复杂的多线程或异步编程...

    Libevent源码分析 pdf文档 带目录

    Libevent是一款高性能的事件通知库,最初由Nick Mathewson和George V. Reilly开发,广泛应用于需要处理多个事件源的网络编程中。该库支持多种操作系统,为跨平台编程提供便利,例如在Linux、BSD、Mac OS X以及...

    libevent-devel-1.4.13-1.x86_64.rpm

    Name : libevent-devel Version : 1.4.13 Vendor : StartCom Ltd_, http://www_startcom_org Release : 1 Date : 2010-04-07 22:14:06 Group : Development/Libraries Source RPM : libevent-1.4.13-1.src.rpm ...

    libevent 2.1.12版本,编译好的全部文件,包含lib和头文件

    **libevent 2.1.12版本详解** Libevent是一个高性能、轻量级的事件通知库,广泛用于网络编程,特别是在服务器端开发中。它提供了异步事件处理的能力,可以高效地处理大量并发连接,使得开发者能够编写出高并发、低...

    libevent对应Android下的库文件

    标题提及的是"libevent对应Android下的库文件",这指的是Libevent,一个开源的、跨平台的事件通知库,用于处理网络和时间触发的异步事件。在Android环境下,由于系统架构和环境的不同,需要对Libevent进行交叉编译,...

    最新版linux fastdfs libevent-2.1.11-stable.tar.gz

    而libevent是一个事件通知库,它使得程序员能够用一种统一的方式来处理网络事件(如TCP、UDP套接字)和其他时间驱动事件(如定时器)。在这个场景中,libevent被FastDFS用来提高其网络通信的效率。 FastDFS的核心...

    libevent-1.4.13-stable的源码包.rar

    libevent-devel-1.4.13-4.el6.x86_64: failure: Packages/libevent-devel-1.4.13-4.el6.x86_64.rpm from c6-media: [Errno 256] No more mirrors to try. libevent-headers-1.4.13-4.el6.noarch: failure: ...

Global site tag (gtag.js) - Google Analytics