libevent项目分析(一) -- 准备阶段

项目的简介

我理解libevent是一个轻量级的,跨平台+高效的(C语言实现)事件驱动库,类似于ACE项目中的ACE_Reactor,它实现了网络通讯套接口I/O事件,定时器事件,信号事件的监听和事件处理函数回调机制。从项目主页可以了解到libevent已经支持 /dev/pollkqueue(2)event portsPOSIX select(2)Windows select()poll(2), and epoll(4)方式的事件监测和驱动机制

项目主页:http://libevent.org/

维基百科:http://zh.wikipedia.org/wiki/Libevent

参考资料:http://blog.csdn.net/sparkliang/article/details/4957667

PS:在分析开源项目代码之前,需首先了解该项目的特性,应用场景和价值,这些信息一方面可以从项目的主页获取,另一方面可以通过搜索引擎从技术论坛,博客等方面获取。最好选择和自己工作/兴趣比较相关的项目,这样有利于分析的深入和坚持,并及时体现收益。


下载源代码

从项目主页可以很方便的下载当前版本的源码,我下载的版本是libevent-2.0.17-stable.tar.gz


代码量分析

通过Wine运行SourceCounter工具对该项目进行代码量统计,可以看到该项目代码量大概5W多行,且代码工程结构简单,比较适合像我这样对开源项目代码分析经验不足的人

PS:在开始分析项目源码之前,分析该项目的代码量可以大致评估该项目的难度和分析计划,分析工程结构可以大致评估该项目的重点部分,以免一开始就满腔热血地栽在一个深坑里(比较复杂的开源项目),而后面又不了了之


编译和安装

在将源码包在本地解压后即可以编译和安装。这里和其他开源项目差不多,没有什么特别的,只是为了方便后面通过调试的手段来分析源码,编译的时候最好编译成debug模式,如下

#./configure --enable-debug-mode --enable-static --enable-thread-support

#make

#make install

安装完成后,libevent库的头文件会安装在/usr/local/include目录下,而库文件会安装在/usr/local/lib目录下,故需确保/usr/local/lib在LD_LIBRARY_PATH变量包含的路径中

PS:卸载的方法

#make uninstall

#make clean


编写测试应用代码

该项目源码包中的sample目录中其实已经有些例子,但我还是情愿参考样例自己写一个,好久没Coding了 :)

mytimer.c : 实现一个定时器事件处理函数,并通过libevent的事件驱动机制定时调用

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

#include <event2/event-config.h>
#include <event2/event.h>
#include <event2/event_struct.h>
#include <event2/util.h>


static void handle_timer(evutil_socket_t fd, short event, void* arg)
{
printf("handle_timer function is called \n");
fflush(stdout);
}

int main(int argc, char** argv)
{
/* Initalize the event library */
struct event_base* base = event_base_new();
if (NULL == base)
{
return -1;
}

/* Initalize one timeout event */
struct event timeout = {0};
event_assign(&timeout, base, -1, EV_PERSIST, handle_timer, (void*)&timeout);

/* Register the event */
struct timeval tv;
evutil_timerclear(&tv);
tv.tv_sec = 2;
event_add(&timeout, &tv);

/*event dispatch*/
event_base_dispatch(base);

event_base_free(base);

return 0;
}

编译 : gcc -g -I/usr/local/include -o mytimer mytimer.c -L/usr/local/lib -levent

运行 : $ ./mytimer 
handle_timer function is called 
handle_timer function is called 
handle_timer function is called 
^C


通过例程调试libevent

通过gdb去调试mytimer时发现其链接的是libevent的动态库,且无法在libevent库的函数上设置断点 :(

安装glibc的静态库:# yum install glibc-static libstdc++-static

静态编译命令:gcc -g -I/usr/local/include -o mytimer mytimer.c -L/usr/local/lib -static -levent -lc -lrt

这样就可以通过gdb调试例程时,在libevent库的函数上设置断点

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/385031.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

混合字符串字符数统计

因为汉字占一个以上字节&#xff0c;如何统计一个既有汉字又有字母的字符串呢&#xff1f; 汉字在计算机中的ASCII是以负数来与其他普通字符的ASCII区分的。 #include<stdio.h> int main() {char buf[256] "你好世界";printf("%d\n",buf[0]); //-60…

清除字符串空格

1.清除字符串中右边的空格 从字符串尾部开始&#xff0c;找到非空格处&#xff0c;将下一个字符置为0即可。 //清除右边空格 #include<stdio.h> int main() {char buf[] "hello world ";int len 0;//calculate the length of stringwhile(buf[len]);le…

浅谈auto_ptr智能指针

引入智能指针&#xff1a;智能指针的实现原理&#xff1a; 资源分配即初始化RAII(Resource Acquisition Is Initialization)&#xff1a; 定义一个类来封装资源的分配和释放&#xff0c;在构造函数完成资源的分配和初始化&#xff0c;在析构函数完成资源的清理&#xff0c;可…

随机数

随机数产生器rand(),头文件为#include<stdlib.h> #include<stdio.h> #include<stdlib.h>int main() {int value;int i;for(i 0; i < 10; i){value rand();printf("value %d\n",value);}return 0; } 运行结果&#xff1a; value 41 value 1…

多重继承之虚继承(主要是为了解决产生的数据冗余问题)

虚继承 是面向对象编程中的一种技术&#xff0c;是指一个指定的基类&#xff0c;在继承体系结构中&#xff0c;将其成员数据实例共享给也从这个基类型直接或间接派生的其它类。形式&#xff1a;在继承定义中包含了virtual关键字的继承关系&#xff0c;如下图中&#xff0c;类A就…

通过syslog接收远程日志

通过syslog接收远程日志通过syslog接收远程主机的日志&#xff0c;需要做一些环境配置。客户机A通过syslog将日志信息发送到服务主机B&#xff08;或称日志采集服务器&#xff09;。以下说明配置过程&#xff08;我的实验环境是&#xff0c;客户机A&#xff1a;Solaris 10&…

linux syslog服务器配置,自动发日志到另一台日志服务器

1.客户端:168.1.20.66修改/etc/syslog.conf 添加syslog.info 168.1.80.302.日志服务器:168.1.80.30修改/etc/sysconf/syslog 修改SYSLOGD_OPTIONS为 "-r -x -m 0" #-r表示允许接收外来的消息&#xff0c;-x表示不解析DNS, #-m 0表示时间戳标记间隔,如果指定只接…

Make文件(一)

基本规则&#xff1a; 目标&#xff1a;依赖 &#xff08;tab&#xff09;规则 目标&#xff1a;需要生成的目标文件 依赖&#xff1a;生成该目标所需的一些文件 规则&#xff1a;由依赖文件生成目标文件的手段 tab&#xff1a;每条规则前必须以tab开头&#xff0c;使用空格不行…

移植驱动完毕后加载时的version magic报错原因以及解决办法

History:2012-02-17Author:yingru移植rt3070的AP驱动到装有fedora14的PC机上时&#xff0c;模块编译完毕后&#xff0c;加载时提示invalid module format。PC机环境介绍&#xff1a;内核版本&#xff1a;2.6.35.6-45.fc14.i686命令行输入dmesg查看最后的日志&#xff0c;发现如…

/proc 虚拟文件系统(实例)

Linux下有一个神奇的目录/proc&#xff0c;经常会运行 cat /proc/cpuinfo 命令查看cpu信息&#xff0c;/proc下的确有cpuinfo文件&#xff0c;但是这个文件不是物理存在的&#xff0c;是软件虚拟出来的&#xff0c;与普通文件不同&#xff0c;该文件是动态的。通过/proc可以实现…

内核模块中对文件的读写

平时网络部分的东西碰的多些&#xff0c;这块一开始还真不知道怎么写&#xff0c;因为肯定和在用户空间下是不同的。google过后&#xff0c;得到以下答案。一般可以用两种方法&#xff1a;第一种是用系统调用。第二种方法是filp->open()等函数。下面分别来说下这两种方法。1…

Makefile文件试错

1成功&#xff1a; src $(wildcard ./*cpp) obj $(patsubst %.cpp,%.o ,$(src))target test$(target) : $(obj)g $(obj) -o $(target) -I/usr/include/mysql -L/usr/lib/mysql/ -lmysqlclient %.o: %.cppg -c $< -o $ -I/usr/include/mysql -L/usr/lib/mysql/ -lmysql…

内核定时器timer_list使用

Linux内核中提供了timer使用的API&#xff0c;做一个简单的记要。 1. 包含的头文件&#xff1a;linux/timer.h 2. 数据类型&#xff1a;struct timer_list; 包含的主要成员&#xff1a; a. data:传递到超时处理函数的参数&#xff0c;主要在多个定时器同时使用时&#xff0c;区…

内存四区

1.代码区&#xff1a; 代码区Code&#xff0c;程序被操作系统加载到内存的时候&#xff0c;所有的可执行代码都加载到代码区&#xff0c;也叫代码段&#xff0c;这块内存是不可以在运行期间修改的。 2. 静态区 所有的全局变量以及程序中的静态变量都存储在静态区。 #include<…

最高效的进(线)程间通信机制--eventfd

我们常用的进程&#xff08;线程&#xff09;间通信机制有管道&#xff0c;信号&#xff0c;消息队列&#xff0c;信号量&#xff0c;共享内存&#xff0c;socket等等&#xff0c;其中主要作为进程&#xff08;线程&#xff09;间通知/等待的有管道pipe和socketpair。线程还有特…

malloc,calloc,realloc

与堆操作相关的两个函数 malloc #include<stdio.h> #include<stdlib.h> #include<string.h>int main() {char *p malloc(10); //内存随机&#xff0c;未做处理int i;for(i 0; i < 10: i){printf(“%d “,p[i]);} free(p);return 0; } 运行结果&…

Linux内核同步机制之completion

内核编程中常见的一种模式是&#xff0c;在当前线程之外初始化某个活动&#xff0c;然后等待该活动的结束。这个活动可能是&#xff0c;创建一个新的内核线程或者新的用户空间进程、对一个已有进程的某个请求&#xff0c;或者某种类型的硬件动作&#xff0c;等等。在这种情况下…

可变参数函数(一)

一个函数可以接受不定数的参数个数&#xff0c;这就是可变参数函数&#xff0c;比较常见的比如printf(),scanf()&#xff1b; printf(const char* format,…); printf(“%d”,i); printf(“%s”,s); printf(“the number is %d,stirng is :%s”,i,s); 变量参数函数的简单实现&a…

Linux内核线程kernel thread详解--Linux进程的管理与调度

内核线程为什么需要内核线程Linux内核可以看作一个服务进程(管理软硬件资源&#xff0c;响应用户进程的种种合理以及不合理的请求)。 内核需要多个执行流并行&#xff0c;为了防止可能的阻塞&#xff0c;支持多线程是必要的。 内核线程就是内核的分身&#xff0c;一个分身可以处…

可变参数函数(二)

函数样例&#xff1a; #include<stdio.h> #include<stdlib.h> #include<stdarg.h>double add(int n,...) {int i 0;double sum 0;va_list argptr;va_start(argptr,n);for(i 0 ; i < n; i){double d va_arg(argptr,double);printf("%d argument …