libevent学习笔记

这篇记录libevent学习过程的问题。

入门

这节基本都是照搬的这篇,为了更熟悉,我照抄一遍。

简介

libevent是一个轻量级的高性能的事件触发的网络库,适用于windows、linux、bsd等多平台,内部使用select、epoll、kqueue等系统调用管理事件机制。

它被众多开源项目使用,如memcached等。

libevent有如下特点:

  • 事件驱动,高性能
  • 轻量级,专注于网络(相对ACE)
  • 开源,代码精炼、易读
  • 跨平台
  • 支持I/O多路复用技术(epoll、poll、dev/poll、select和kqueue等),在不同操作系统下,做了多路复用模型的抽象,可以选择使用不同的模型,通过事件函数提供服务
  • 支持I/O,定时器和信号等事件
  • 采用Reactor模式

安装

原文有通用的安装方法,我太懒了。我的centos7试试yum是否可以:

1
2
3
4
yum install libevent-devel
rpm -qa|grep libevent #居然还是libevent2,很好
rpm -ql libevent-devel #头文件、库文件都在
whereis libevent #确实能找到

功能

libevent提供了事件通知,io缓存事件,定时器,超时,异步解析dns,事件驱动的http server以及一个rpc框架。下面介绍一下:

  • 事件通知:当文件描述符可读可写时将执行回调函数。
  • io缓存:缓存事件提供了输入输出缓存,能自动的读入和写入,用户不必直接操作io。
  • 定时器:libevent提供了定时器的机制,能够在一定的时间间隔之后调用回调函数。
  • 信号:触发信号,执行回调。
  • 异步的dns解析:libevent提供了异步解析dns服务器的dns解析函数集。
  • 事件驱动的http服务器:libevent提供了一个简单的,可集成到应用程序中的http服务器。
  • RPC客户端服务器框架:libevent为创建RPC服务器和客户端创建了一个RPC框架,能自动的封装和解封数据结构。

例子

libevent是一个典型的reactor模式的实现。简单介绍:

普通的函数调用机制如下:程序调用某个函数、函数执行、程序等待、程序将结果返回给调用程序,即顺序执行。

而reactor模式的基本流程如下:应用程序需要提供相应的接口并且注册到reactor反应器上,如果相应的事件发生的话,那么reactor将自动调用相应的注册的接口函数(类似于回调函数)通知你,所以libevent是事件触发的网络库。

看个简单例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>
#include <event.h>
void onTime(int sock, short event, void *arg)
{
printf("hello, world.\n");
struct timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 0;
event_add((struct event*)arg, &tv);
}

int main()
{
event_init();
struct event ev_time;
evtimer_set(&ev_time, onTime, &ev_time);
struct timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 0;
event_add(&ev_time, &tv);
event_dispatch();
return 0;
}

执行命令:

1
2
gcc test1.c -levent #编译
./a.out #运行

深入浅出

这章完全抄自https://aceld.gitbooks.io/libevent/content/,这里就是为这个教程做个学习笔记。