Libevent
Libevent是一个用C语言编写的、轻量级的开源高性能事件通知库,主要有以下几个亮点:
事件驱动( event-driven),高性能;
轻量级,专注于网络,不如 ACE 那么臃肿庞大;
源代码相当精炼、易读;
跨平台,支持 Windows、 Linux、 *BSD 和 Mac Os;
支持多种 I/O 多路复用技术, epoll、 poll、 dev/poll、 select 和 kqueue 等;
支持 I/O,定时器和信号等事件;注册事件优先级。
基于“事件”异步通信模型 ---依赖回调
注册异步事件,检测异步事件,根据事件的触发先后顺序,调用相对应回调函数处理事件。
处理的事件包括:网络 io 事件、定时事件以及信号事件
。这三个事件驱动着服务器的运行。
1. 网络io事件:
linux:epoll、poll、select
mac:kqueue
window:iocp
2. 定时事件:
红黑树
最小堆:二叉树、四叉树
跳表
时间轮
3. 信号事件
源码包安装: 参考readme文件
tar zxvf libevent-2.1.12-stable.tar.gz //解压
cd libevent-2.1.12-stable/ //进入解压目录
./configure //检查安装环境 生成makefile
make //生成 .o 和 可执行文件
make install //将必要的资源cp至系统指定目录
cd sample/ //进入 sample 目录,运行demo验证库安装使用情况
gcc hello-world.c -o hello -levent //编译使用库的.c时,需添加 -l选项+库名
./server //执行
./nc 127.1 9995 //另起一终端执行
若执行 ./server 提示错误:
./hello: error while loading shared libraries: libevent-2.1.so.7: cannot open shared object file: No such file or directory
产生原因:在运行时,程序无法找到libevent-2.1.so.7
这个动态库,因为该动态库在默认安装时,存放的路径在/usr/local/lib
下,不在系统的默认查找路径内。
解决方法:
第一步:
sudo echo "/usr/local/lib" >> /etc/ld.so.conf
//无报错则直接转第二步
//若报错(bash: /etc/ld.so.conf: Permission denied)
vim /etc/ld.so.conf //在文件末尾加上 /usr/local/lib
第二步:
sudo ldconfig //更新使配置生效
1)libevent框架
头文件:#include<event2/event.h>
1、创建 event_base
(乐高底座)
struct event_base *event_base_new(void);
struct event_base *base = event_base_new();
2、创建 事件event
- 常规事件
event
-->event_new();
- 带缓冲区的事件
bufferevent
-->bufferevent_socket_new();
3、将事件 添加到 base
上
int event_add(struct event *ev, const struct timeval *tv)
4、循环监听事件满足
int event_base_dispatch(base);
event_base_dispatch(base)
5、释放 event_base
void event_base_free(base);
2)常规事件event
①创建一个事件
struct event *ev;
struct event *event_new(struct event_base *base, evutil_socket_t fd,
short what, event_callback_fn cb, void *arg)
base: event_base_new()返回值
fd: 绑定到 event 上的 文件描述符
what: 对应事件(r,w,e)
EV_READ //一次 读事件
EV_WRTIE //一次 写事件
EV_PERSIST //持续出发 结合 event_base_dispatch函数使用,生效。
cb: 一旦事件满足监听条件,回调的函数
typedef void(*event_callback_fn)(evutil_socket_t fd, short, void *) //(重要)
arg: 回调函数的参数
返回值: 成功创建的 event
②添加事件到 event_base
int event_add(struct event *ev, const struct timeval *tv);
ev: event_new()的返回值
tv: NULL
从event_base上摘下事件
int event_del(struct event *ev);
ev: event_new()
的返回值
③销毁事件
int event_free(struct event *ev);
ev: event_new()的返回值
myread.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/stat.h>
#include <event2/event.h>
void sys_err(const char *str)
{
perror(str);
exit(1);
}
void read_cb(evutil_socket_t fd, short what, void *arg)
{
char buf[1024] = {0};
int len = read(fd, buf, sizeof(buf));
printf("what = %s, read from write : %s\n",
what & EV_READ ? "read YES" : "read NO", buf);
sleep(1);
return ;
}
int main(int argc, char *argv[])
{
//创建 fifo
unlink("testfifo");
mkfifo("testfifo", 0644);
//打开 fifo 的读端
int fd = open("testfifo", O_RDONLY | O_NONBLOCK);
if(fd == -1){
sys_err("open err");
}
//创建 event_base
struct event_base *base = event_base_new();
//创建事件
struct event *ev = NULL;
//添加事件到 event_base 上
/*struct event *event_new(struct event_base *base, evutil_socket_t fd,
short what, event_callback_fn cb, void *arg)*/
ev = event_new(base, fd, EV_READ | EV_PERSIST, read_cb, NULL);
//添加事件到 event_base 上
//int event_add(struct event *ev, const struct timeval *tv);
event_add(ev, NULL);
//启动循环
//int event_base_disppatch(struct event_base *base);
event_base_dispatch(base); // 相当于包含 while(1)
//销毁 event_base
event_base_free(base);
return 0;
}
mywrite.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/stat.h>
#include <event2/event.h>
void sys_err(const char *str)
{
perror(str);
exit(1);
}
void write_cb(evutil_socket_t fd, short what, void *arg)
{
char buf[] = "hello libevent";
write(fd, buf, strlen(buf));
sleep(1);
return ;
}
int main(int argc, char *argv[])
{
//打开 fifo 的写端
int fd = open("testfifo", O_RDONLY | O_NONBLOCK);
if(fd == -1){
sys_err("open err");
}
//创建 event_base
struct event_base *base = event_base_new();
//创建 事件对象
struct event *ev = NULL;
//添加事件到 event_base 上
/*struct event *event_new(struct event_base *base, evutil_socket_t fd,
short what, event_callback_fn cb, void *arg)*/
ev = event_new(base, fd, EV_WRITE | EV_PERSIST, write_cb, NULL);
//添加事件到 event_base 上
//int event_add(struct event *ev, const struct timeval *tv);
event_add(ev, NULL);
//启动循环
//int event_base_disppatch(struct event_base *base);
event_base_dispatch(base); // 相当于包含 while(1)
//销毁 event_base
event_base_free(base);
return 0;
}
编译:
gcc myread.c -o myread -levent
gcc mywrite.c -o mywrite -levent
④未决和非未决
未决:有资格被处理,但还没有被处理
非未决:没有资格被处理