赞
踩
Libevent 是一个用C语言编写的、轻量级的开源高性能事件通知库,主要有以下几个亮点:事件驱动( event-driven),高性能;轻量级,专注于网络,不如 ACE 那么臃肿庞大;源代码相当精炼、易读;跨平台,支持 Windows、 Linux、 *BSD 和 Mac Os;支持多种 I/O 多路复用技术, epoll、 poll、 dev/poll、 select 和 kqueue 等;支持 I/O,定时器和信号等事件;注册事件优先级。
Libevent 已经被广泛的应用,作为底层的网络库;比如 memcached、 Vomit、 Nylon、 Netchat等等。
官网:libevent
我这里用的是2.1.8版本,linux使用的是ubuntu20.4。使用原码安装。
- (1)解压
- (2)./configure # 检查安装环境 生成 makefile
- (3)make # 生成 .o 和 可执行文件
- (4)sudo make install # 将必要的资源cp置系统指定目录。
进入sample路径下
这里有一些小demo可以测试书否安装成功
这样即表示安装成功。
头文件在include里面
查看支持哪些多路io
- /*************************************************************************
- > File Name: 01event.c
- > Author: Winter
- > Created Time: 2022年02月17日 星期四 20时58分11秒
- ************************************************************************/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <pthread.h>
- #include <event2/event.h>
-
-
-
- int main(int argc, char* argv[])
- {
- struct event_base* base = event_base_new(); // 创建base
- int i;
-
- const char** buff1;
- buff1 = event_get_supported_methods(); // 查看支持哪些多路io
- for (i = 0; i < 10; i++) {
- printf("buff1[i] = %s\n", buff1[i]);
- }
- return 0;
- }

注意编译时,添加-levent
查看当前使用的多路IO
- /*************************************************************************
- > File Name: 01event.c
- > Author: Winter
- > Created Time: 2022年02月17日 星期四 20时58分11秒
- ************************************************************************/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <pthread.h>
- #include <event2/event.h>
-
-
-
- int main(int argc, char* argv[])
- {
- struct event_base* base = event_base_new(); // 创建bas
- const char *buff2;
- buff2 = event_base_get_method(base); // 查看当前使用的多路IO
- printf("buff2 = %s\n", buff2);
-
- return 0;
- }

- 1. 创建 event_base (乐高底座)
- 2. 创建 事件evnet
- 3. 将事件 添加到 base上
- 4. 循环监听事件满足
- 5. 释放 event_base
(1)创建 event_base (乐高底座)
- struct event_base *event_base_new(void);
- struct event_base *base = event_base_new();
(2)创建 事件evnet
创建事件分为两种:常规事件(event_new)和带缓冲区的事件(bufferevent_socket_new)
- 常规事件 event --> event_new();
- 带缓冲区的事件 bufferevent --> bufferevent_socket_new();
(3)将事件 添加到 base上
int event_add(struct event *ev, const struct timeval *tv)
(4)循环监听事件满足
int event_base_dispatch(struct event_base *base);
(5)释放 event_base
event_base_free(base);
创建事件event
- 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
读操作
- /*************************************************************************
- > File Name: myread.c
- > Author: Winter
- > Created Time: 2022年02月18日 星期五 21时07分03秒
- ************************************************************************/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <pthread.h>
- #include <fcntl.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <event2/event.h>
-
- // 回调函数
- void read_cb(evutil_socket_t fd, short what, void* arg) {
- // 读管道
- char buff[1024] = {0};
- int len = read(fd, buff, sizeof(buff));
-
- printf("read event : %s \n", what & EV_READ ? "YES" : "NO");
- printf("data len = %d, buff = %s\n", len, buff);
- sleep(1);
- }
-
-
- int main(int argc, char* argv[])
- {
- unlink("myfifo");
- // 创建有名fifo
- int res = mkfifo("myfifo", 0664);
- if (res == -1) {
- perror("mkfifo error\n");
- exit(1);
- }
- // 打开fifo
- int fd = open("myfifo", O_RDONLY | O_NONBLOCK); // 非阻塞只读
- if (fd == -1) {
- perror("open error\n");
- exit(1);
- }
-
- // 创建event_base
- struct event_base* base = event_base_new();
-
- // 创建事件 EV_PERSIST是持续读
- struct event* ev = event_new(base, fd, EV_READ | EV_PERSIST, read_cb, NULL);
- // struct event* ev = event_new(base, fd, EV_READ, read_cb, NULL);
- // 添加事件
- event_add(ev, NULL);
-
- // 事件循环
- event_base_dispatch(base); // while (1) { epoll }
-
- // 释放资源
- event_free(ev);
- event_base_free(base);
- close(fd);
- return 0;
- }

写操作
- /*************************************************************************
- > File Name: mywrite.c
- > Author: Winter
- > Created Time: 2022年02月18日 星期五 21时24分04秒
- ************************************************************************/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <pthread.h>
- #include <event2/event.h>
- #include <fcntl.h>
-
- // 回调函数
- void write_cb(evutil_socket_t fd, short what, void* arg) {
- // 写管道
- char buff[1024] = {0};
- static int num = 0;
- sprintf(buff, "hello world - %d", num++);
- write(fd, buff, strlen(buff) + 1);
- sleep(1);
- }
-
- int main(int argc, char* argv[])
- {
- // 与myread.c配套,但是要先打开myread程序
- // 打开管道
- int fd = open("myfifo", O_WRONLY | O_NONBLOCK);
- if (fd == -1) {
- perror("open error\n");
- exit(1);
- }
-
- // 创建event_base
- struct event_base* base = event_base_new();
-
- // 创建写事件 EV_PERSIST是持续写
- struct event* ev = event_new(base, fd, EV_WRITE | EV_PERSIST, write_cb, NULL);
- // struct event* ev = event_new(base, fd, EV_WRITE, write_cb, NULL);
- // 添加事件
- event_add(ev, NULL);
-
- // 事件循环
- event_base_dispatch(base);
-
- // 释放资源
- event_free(ev);
- event_base_free(base);
- close(fd);
-
- return 0;
- }

测试
这里只测试了带有EV_PERSIST参数的event_new函数。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。