libevent笔记——简单介绍

背景

libevent

libevent – an event notification library

官方定义:libevent是一个事件通知的库。更详细的介绍参考官方的就够了,这里我摘抄一下,并做一些注释

The libevent API provides a mechanism to execute a callback function when a specific event occurs on a file descriptor or after a timeout has been reached. Furthermore, libevent also support callbacks due to signals or regular timeouts.

libevent提供API来支持在文件描述符发生事件或者超时后调用回调函数的机制。

libevent is meant to replace the event loop found in event driven network servers. An application just needs to call event_dispatch() and then add or remove events dynamically without having to change the event loop.

libevent目的是在事件驱动的网络服务器中取代事件循环。应用只需要调用event_dispatch()然后动态添加或者删除事件,并不需要去修改事件循环。总结一下:libevent是为了取缔在应用中手写事件循环。

Currently, libevent supports dev/poll, kqueue(2), event ports, POSIX select(2), Windows select(), poll(2), and epoll(4). The internal event mechanism is completely independent of the exposed event API, and a simple update of libevent can provide new functionality without having to redesign the applications. As a result, Libevent allows for portable application development and provides the most scalable event notification mechanism available on an operating system. Libevent can also be used for multi-threaded applications, either by isolating each event_base so that only a single thread accesses it, or by locked access to a single shared event_base. Libevent should compile on Linux, *BSD, Mac OS X, Solaris, Windows, and more.

目前,libevent支持/dev/poll, kqueue, event ports, POSIX select, Windows select, poll, 和 epoll

Libevent additionally provides a sophisticated framework for buffered network IO, with support for sockets, filters, rate-limiting, SSL, zero-copy file transmission, and IOCP. Libevent includes support for several useful protocols, including DNS, HTTP, and a minimal RPC framework.

More information about event notification mechanisms for network servers can be found on Dan Kegel’s “The C10K problem” web page.

阅读libevent动机

  1. libevent被广泛应用,是一个成熟的、稳定的事件驱动库
  2. 阅读一下优秀的开源C代码,学习

libevent源码结构

整个源码包解压下来,根目录里面是一堆信息文件、源代码、CMakeLists文件、configure相关文件以及测试例子等文件夹。
其中:

  1. README.md是项目说明文件,编译安装可以参考。
  2. include文件夹是库对外提供的头文件,使用libevent库的时候需要包含。
  3. 其他文件

这里再说下include文件夹,它里面有两层头文件,其中最外面的几个头文件都是对里面event2文件夹中头文件的包装,每个头文件开头都有类似一段话The header is deprecated in Libevent 2.0 and later; please use instead.。原因是libevent在2.0之后变化了很多,为了兼容旧代码才这样做。

include/
├── evdns.h
├── event2
│   ├── buffer_compat.h
│   ├── bufferevent_compat.h
│   ├── bufferevent.h
│   ├── bufferevent_ssl.h
│   ├── bufferevent_struct.h
│   ├── buffer.h
│   ├── dns_compat.h
│   ├── dns.h
│   ├── dns_struct.h
│   ├── event_compat.h
│   ├── event.h
│   ├── event_struct.h
│   ├── http_compat.h
│   ├── http.h
│   ├── http_struct.h
│   ├── keyvalq_struct.h
│   ├── listener.h
│   ├── rpc_compat.h
│   ├── rpc.h
│   ├── rpc_struct.h
│   ├── tag_compat.h
│   ├── tag.h
│   ├── thread.h
│   ├── util.h
│   └── visibility.h
├── event.h
├── evhttp.h
├── evrpc.h
├── evutil.h
└── include.am

接着,我们看下编译构建文件夹,这里我们按照README中的方法,新建文件夹build作为构建目录。

build/
├── bin
├── CMakeCache.txt
├── CMakeFiles
├── cmake_install.cmake
├── compile_commands.json
├── CTestTestfile.cmake
├── DartConfiguration.tcl
├── include
├── lib
├── LibeventConfig.cmake
├── LibeventConfigVersion.cmake
├── libevent_core.pc
├── libevent_extra.pc
├── libevent_openssl.pc
├── libevent.pc
├── libevent_pthreads.pc
├── LibeventTargets-shared.cmake
├── LibeventTargets-static.cmake
├── Makefile
├── Testing
├── tmp
├── Uninstall.cmake
└── verify_tests.sh

其中:

  1. bin文件夹是一些测试例子程序
  2. CMakeFiles文件夹是一些中间cmake配置
  3. include文件夹是cmake生成的头文件,这里面定义了不同的系统以及配置,帮助libevent实现跨平台
  4. lib文件夹是编译生成的动态库和静态库
  5. 其他文件

libevent文档

libevent可以在构建时生成doxygen文档和pdf文档。

  • configure --enable-doxygen-doc 生成doxygen html文档
  • configure --enable-doxygen-pdf 生成pdf文档(需要pdflatex工具)

关于doxygen的介绍参考:Doxygen使用。

libevent库的使用

编译完后,我们第一步肯定是要学习怎么在自己的项目中使用这个库。
在编译完后,libevent会产生下面几个动态库和静态库(build/lib):

# 编译选项 -levent
libevent-2.1.so.7.0.1
libevent.a
# 编译选项 -levent_core
libevent_core-2.1.so.7.0.1
libevent_core.a
# 编译选项 -levent_extra
libevent_extra-2.1.so.7.0.1
libevent_extra.a
# 编译选项 -levent_openssl -levent
libevent_openssl-2.1.so.7.0.1
libevent_openssl.a
# 编译选项 -levent_pthreads -levent
libevent_pthreads-2.1.so.7.0.1
libevent_pthreads.a

一个例子 test-libevent.c


#include
#include
#include"libevent-2.1.12-stable/include/event2/event.h"    // libevent库的头文件
#include"libevent-2.1.12-stable/include/event2/thread.h"
 
 
void cmd_cb(int fd, short events, void *arg)
{
    char buf[1024];
    printf("in the cmd_cb\n");
 
    read(fd, buf, sizeof(buf));
}
 
 
int main()
{
    evthread_use_pthreads();
 
    //使用默认的event_base配置
    struct event_base *base = event_base_new();
 
    struct event *cmd_ev = event_new(base, STDIN_FILENO,
                                     EV_READ | EV_PERSIST, cmd_cb, NULL);
 
    event_add(cmd_ev, NULL); //没有超时
 
    event_base_dispatch(base);
 
    return 0;
}

编译:

# 使用编译出来的动态库,需要通过-L指定编译时使用的库路径,同时需要使用rpath选项指定程序运行时使用的库路径(避免使用系统自带的库)
gcc  test-libevent.c -levent -levent_pthreads -levent_extra -L/build/lib/ -Wl,-rpath,build/lib
ldd a.out 
        linux-vdso.so.1 (0x00007ffc0d558000)
        libevent-2.1.so.7 => build/lib/libevent-2.1.so.7 (0x00007f387b284000)
        libevent_pthreads-2.1.so.7 => build/lib/libevent_pthreads-2.1.so.7 (0x00007f387b27f000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f387b07f000)
        libevent_core-2.1.so.7 => /home/czw/workspace/czw/libevent-notes/notes/build/lib/libevent_core-2.1.so.7 (0x00007f387b040000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f387b2f0000)
# 使用编译出来的静态库,直接把静态文件作为编译时的文件
gcc  test-libevent.c build/lib/libevent.a build/lib/libevent_pthreads.a
ldd a.out 
        linux-vdso.so.1 (0x00007ffcadb80000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f817f4a2000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f817f6c9000)

reference

  1. https://libevent.org/

你可能感兴趣的:(Read_Notes,libevent,服务器,linux)