Libevent

和之前的《Libevent工作流程探究》一样,这里也是用一个例子来探究bufferevent的工作流程。具体的例子可以参考《Libevent使用例子,从简单到复杂》,这里就不列出了。其实要做的例子也就是bufferevent_socket_new、bufferevent_setcb、bufferevent_enable这几个函数。 ? ? ? ?
dexcoder 1年前发布
锁操作: ? ? ? ??在 前一篇博文可以看到很多函数在操作前都需要对这个evbuffer进行加锁。同event_base不同,如果evbuffer支持锁的话,要显式地调用函数evbuffer_enable_locking。 //buffer.c文件 int//参数可以是一个锁变量也可以是NULL evbuffer_enable_locking(struct ev
dexcoder 1年前发布
对于非阻塞IO的网络库来说,buffer几乎是必须的。Libevent在1.0版本之前就提供了buffer功能。现在来看一下Libevent的buffer。 buffer相关结构体: ? ? ? ??Libevent为buffer定义了下面的结构体: //evbuffer-internal.h文件 struct evbuffer_chain; struct evbuffer { str
dexcoder 1年前发布
使用evconnlistener: ? ? ? ? 基于event和event_base已经可以写一个CS模型了。但是对于服务器端来说,仍然需要用户自行调用socket、bind、listen、accept等步骤。这个过程有点繁琐,为此在2.0.2-alpha版本的Libevent推出了一些对应的封装函数。 ? ? ? ??用户只需初始化struct
dexcoder 1年前发布
?Libevent定义了一系列的可移植的兼容类型和函数。这使得在各个系统上都有一致的效果,Libevent一般都会在兼容通用类型和函数的前面加上ev或evutil前缀。 ? ? ? ??在实现上,Libevent都是使用条件编译+宏定义的方式。使用这种方式,同一个宏名字,可以使得在不同的系统上, 编
dexcoder 1年前发布
? ? ? ??Libevent提供了一些与event相关的操作函数和操作。本文就重点讲一下这方面的源代码。 ? ? ? ? 在Libevent中,无论是event还是event_base,都是使用指针而不会使用变量。实际上,如果查看Libevent不同的版本,就可以发现event和event_base这两个结构体的成员是不同的。
dexcoder 1年前发布
? ? ? ??前面的博文已经说到,如果要对多个超时event同时进行监听,就要对这些超时event进行集中管理,能够方便地(时间复杂度小)获取、加入、删除一个event。 ? ? ? ??在之前的Libevent版本,Libevent使用小根堆管理这些超时event。小根堆的插入和删除时间复杂度都是O(logN)。
dexcoder 1年前发布
基本时间操作函数: ? ? ? ??Libevent采用的时间类型是struct? timeval,这个类型在很多平台都提供了。此外,Libevent还提供了一系列的时间操作函数。比如两个struct timeval相加、相减、比较大小。有些平台直接提供了一些时间操作函数,但有些则没有,那么Libevent就自己实现
dexcoder 1年前发布
如何成为超时event: ? ? ?? ? ? ? ???Libevent允许创建一个超时event,使用evtimer_new宏。 //event.h文件 #define evtimer_new(b, cb, arg) event_new((b), -1, 0, (cb), (arg)) ? ? ? ??从宏的实现来看,它一样是用到了一般的event_new,并且不使用任何的文件描
dexcoder 1年前发布
一般来说,是主线程执行event_base_dispatch函数。本文也是如此,如无特别说明,event_base_dispatch函数是由主线程执行的。 notify的理由: ? ? ? ? 本文要说明的问题是,当主线程在执行event_base_dispatch进入多路IO复用函数时,会处于休眠状态,休眠前解锁。此时,其他线
dexcoder 1年前发布
信号event的工作原理: ? ? ? ??前面讲解了Libevent怎么对一个IO事件进行监听,现在来讲一下Libevent怎么监听信号。Libevent对于信号的处理是采用统一事件源的方式。简单地说,就是把信号也转换成IO事件,集成到Libevent中。 ? ? ? ? 统一事件源的工作原理是这样的:假如用户
dexcoder 1年前发布
?event_base允许用户对它里面的event设置优先级,这样可以使得有些更重要的event能够得到优先处理。 ? ? ? ? Libevent实现优先级功能的方法是:用一个激活队列数组来存放激活event。即数组的元素是一个激活队列,所以有多个激活队列。并且规定不同的队列有不同的优先级。 ? ?
dexcoder 1年前发布
之前的博文讲了很多Libevent的基础构件,现在以一个实际例子来初步探究Libevent的基本工作流程。由于还有很多Libevent的细节并没有讲所以,这里的探究还是比较简洁,例子也相当简单。 #include<unistd.h> #include<stdio.h> #include<event.h> #include&
dexcoder 1年前发布
之前的博文讲了怎么实现线程、锁、内存分配、日志等功能的跨平台。Libevent最重要的跨平台功能还是实现了多路IO接口的跨平台(即Reactor模式)。这使得用户可以在不同的平台使用统一的接口。这篇博文就是来讲解Libevent是怎么实现这一点的。 ? ? ? ??Libevent在实现线程、内存分
dexcoder 1年前发布
?前面的博文都是讲一些Libevent的一些辅助结构,现在来讲一下关键结构体:event_base。 ? ? ? ??这里作一个提醒,在阅读Libevent源码时,会经常看到backend这个单词。其直译是“后端”。实际上其指的是Libevent内部使用的多路IO复用函数,多路IO复用函数就是select、poll、epo
dexcoder 1年前发布
相关结构体: ? ? ? ? ? ? ? ??因为event_signal_map结构体实在太简单了,所以不像event_io_map那样,有一个专门的文件。由于没有专门的文件,那么只能从蛛丝马迹上探索这个event_signal_map结构了。 ? ? ? ??通过一些搜索,可以得到与event_signal_map相关联的一些结构体有下
dexcoder 1年前发布
上一篇博客说到了TAILQ_QUEUE队列,它可以把多个event结构体连在一起。是一种归类方式。本文也将讲解一种将event归类、连在一起的结构:哈希结构。 哈希结构体: ? ? ? ? 哈希结构由下面几个结构体一起配合工作: struct event_list { struct event *tqh_first; st
dexcoder 1年前发布
?Libevent源码中有一个queue.h文件,位于compat/sys目录下。该文件里面定义了5个数据结构,其中TAILQ_QUEUE是使得最广泛的。本文就说一下这个数据结构。 队列结构体: ? ? ? ??TAILQ_QUEUE由下面两个结构体一起配合工作。 #define TAILQ_HEAD(name, type) \ struct name
dexcoder 1年前发布
Debug锁操作: ? ? ? ?? ? ? ??Libevent还支持对锁操作的一些检测,进而捕抓一些典型的锁错误。Libevent检查: 解锁自己(线程)没有持有的锁 在未解锁前,自己(线程)再次锁定一个非递归锁。 ? ? ? ??Libevent通过一些变量记录锁的使用情况,当检查到这些锁的错误使用时,就调用
dexcoder 1年前发布
Libevent提供给用户的可见多线程API都在thread.h文件中。在这个文件提供的API并不多。基本上都是一些定制函数,像前面几篇博文说到的,可以为Libevent定制用户自己的多线程函数。 开启多线程: ? ? ? ? Libevent默认是不开启多线程的,也没有锁、条件变量这些东西。这点和前面
dexcoder 1年前发布