关于libevent库
Libevent 是一个轻量级的开源高性能网络库,有几个显著的亮点:
- 事件驱动(event-driven),高性能;
- 轻量级,专注于网络,不如 ACE 那么臃肿庞大;
- 源代码相当精炼、易读;
- 跨平台,支持 Windows、 Linux、 *BSD 和 Mac Os;
- 支持多种 I/O 多路复用技术, epoll、 poll、 dev/poll、 select 和 kqueue 等;
- 支持 I/O,定时器和信号等事件;
- 注册事件优先级;
Libevent 已经被广泛的应用,作为底层的网络库;比如 memcached、Vomit、Nylon、Netchat等等。
关于libevent的安装
下载安装包
解压
# tar zxvf libevent-2.0.10-stable.tar.gz
进入目录
# cd libevent-2.0.10-stable
切换到root
# su
安装gcc
# yum install gcc
设置安装路径
不加这句的话,默认安装目录在/usr/local/lib
# ./configure --prefix=/usr
编译
# make
安装
# make install
测试libevent是否安装成功:
# ls -al /usr/lib | grep libevent
lrwxrwxrwx 1 root root 21 11?? 12 17:38 libevent-1.2.so.1 -> libevent-1.2.so.1.0.3
-rwxr-xr-x 1 root root 263546 11?? 12 17:38 libevent-1.2.so.1.0.3
-rw-r–r– 1 root root 454156 11?? 12 17:38 libevent.a
-rwxr-xr-x 1 root root 811 11?? 12 17:38 libevent.la
lrwxrwxrwx 1 root root 21 11?? 12 17:38 libevent.so -> libevent-1.2.so.1.0.3
安装问题
频繁报了openssl问题
- 首先先排查你究竟装了libevent没有,我在给朋友重新配置环境时候,怎么都会报错,该试的都试了,最后结果在/usr/local/lib/下面看到了一堆的libevent.so,这个真的是,太无语了。
言归正传,如果你不是设置过./configure的话,默认安装目录在/usr/local/lib下面,装前你先看一看嘛,又不吃亏,不行的话可以 find 一下嘛 如果真的不行,那么可能openssl的目录不在系统的默认路径置中,那么可以加入一个软连接
# ln -sf /usr/local/ssl/include/openssl /usr/include/openssl
如果还是有问题,那么可能是你的openssl的版本太低,可以试试升级
# yum update openssl -y
- 首先先排查你究竟装了libevent没有,我在给朋友重新配置环境时候,怎么都会报错,该试的都试了,最后结果在/usr/local/lib/下面看到了一堆的libevent.so,这个真的是,太无语了。
libevent的使用
第一个例子:
int main()
{
int sockfd = create_socket();
struct event_base * base = event_init();
assert( base != NULL );
struct event* ev_sock = event_new(base,sockfd,EV_READ|EV_PERSIST,accept_cb,(void*)base);
assert( ev_sock != NULL );
event_add(ev_sock,NULL);
event_base_dispatch(base);
event_free(ev_sock);
event_base_free(base);
}
第二个例子:
int main()
{
struct event_base *base = event_init();
struct event *signal_event = evsignal_new(base,SIGINT,signal_cb,base);
event_add(signal_event,NULL);
struct timeval tv = {3,0};
struct event *timeout_event = evtimer_new(base,timeout_cb,NULL);
event_add(timeout_event,&tv);
event_base_dispatch(base);
event_free(timeout_event);
event_free(signal_event);
event_base_free(base);
}
这两个简单例子反映了event库使用时的代码逻辑:
- 首先用event_init()来构建一个event_base对象
创建具体的事件event *用来表示具体事件,用evsignal_new,或者evtimer_new来注册事件,两个函数本质上来说都是对函数event_new()的封装
struct event* event_new(struct event_base *base, evutil_socket_t fd, short event, void (*cb)(evutil_socket_t fd, short event, void *arg),void *arg); //short event所使用的宏名 #define EV_TIMEOUT 0x01 //定时时间 #define EV_READ 0x01 //可读时间 #define EV_WRITE 0x01 //可写时间 #define EV_SIGNAL 0x01 //信号时间 #define EV_PERSIST 0x01 //永久时间 #define EV_ET 0x20 //边缘触发,epoll下的ET模式
- 调用event_add()函数,将事件注册到事件表中去
- 调用event_base_dispatch()执行事件循环
事件结束后,利用event_free()来释放事件资源,利用event_base_free()来释放event_free对象
如果事件表中都是一次性事件,一次事件触发后会结束事件从此不再监听
evtimer_new()默认的超时事件是一个一次性的事件,如果需要多次监听,可以从event_new中进行详细的设置
event_new()中,信号事件直接在fd处写入信号名称,如果是超时事件,则用-1来表明