当前位置:   article > 正文

libevent库学习(1)

libevent库

一、初识

1、libevent介绍

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等等。

2、安装

官网:libevent

我这里用的是2.1.8版本,linux使用的是ubuntu20.4。使用原码安装。

  1. 1)解压
  2. 2)./configure       # 检查安装环境 生成 makefile
  3. 3)make          # 生成 .o 和 可执行文件
  4. 4)sudo make install # 将必要的资源cp置系统指定目录。

3、检查是否安装成功

进入sample路径下

 这里有一些小demo可以测试书否安装成功

 这样即表示安装成功。

4、查看安装路径

 头文件在include里面

5、框架相关的不常用函数

查看支持哪些多路io

  1. /*************************************************************************
  2. > File Name: 01event.c
  3. > Author: Winter
  4. > Created Time: 2022年02月17日 星期四 20时58分11秒
  5. ************************************************************************/
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <unistd.h>
  10. #include <pthread.h>
  11. #include <event2/event.h>
  12. int main(int argc, char* argv[])
  13. {
  14. struct event_base* base = event_base_new(); // 创建base
  15. int i;
  16. const char** buff1;
  17. buff1 = event_get_supported_methods(); // 查看支持哪些多路io
  18. for (i = 0; i < 10; i++) {
  19. printf("buff1[i] = %s\n", buff1[i]);
  20. }
  21. return 0;
  22. }

 注意编译时,添加-levent

查看当前使用的多路IO

  1. /*************************************************************************
  2. > File Name: 01event.c
  3. > Author: Winter
  4. > Created Time: 2022年02月17日 星期四 20时58分11秒
  5. ************************************************************************/
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <unistd.h>
  10. #include <pthread.h>
  11. #include <event2/event.h>
  12. int main(int argc, char* argv[])
  13. {
  14. struct event_base* base = event_base_new(); // 创建bas
  15. const char *buff2;
  16. buff2 = event_base_get_method(base); // 查看当前使用的多路IO
  17. printf("buff2 = %s\n", buff2);
  18. return 0;
  19. }

二、libevent封装的框架思想

1、libevent框架

  1. 1. 创建 event_base (乐高底座)
  2. 2. 创建 事件evnet
  3. 3. 将事件 添加到 base上
  4. 4. 循环监听事件满足
  5. 5. 释放 event_base

(1)创建 event_base       (乐高底座)

  1. struct event_base *event_base_new(void);
  2. struct event_base *base = event_base_new();

(2)创建 事件evnet

创建事件分为两种:常规事件(event_new)和带缓冲区的事件(bufferevent_socket_new)

  1. 常规事件 event --> event_new();
  2. 带缓冲区的事件 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);

2、使用fifo读写(常规事件)

创建事件event

  1. struct event *event_new(struct event_base *base,evutil_socket_t fd,short what event_callback_fn cb; void *arg);
  2. 参数:
  3. base: event_base_new()返回值
  4. fd: 绑定到 event 上的 文件描述符
  5. what:对应的事件(r、w、e)
  6. EV_READ 一次 读事件
  7. EV_WRTIE 一次 写事件
  8. EV_PERSIST 持续触发。 结合 event_base_dispatch 函数使用,生效。
  9. cb:一旦事件满足监听条件,回调的函数。
  10. typedef void (*event_callback_fn)(evutil_socket_t fd, short, void *)
  11. arg: 回调的函数的参数。
  12. 返回值:成功创建的 event

读操作

  1. /*************************************************************************
  2. > File Name: myread.c
  3. > Author: Winter
  4. > Created Time: 2022年02月18日 星期五 21时07分03秒
  5. ************************************************************************/
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <unistd.h>
  10. #include <pthread.h>
  11. #include <fcntl.h>
  12. #include <sys/stat.h>
  13. #include <sys/types.h>
  14. #include <event2/event.h>
  15. // 回调函数
  16. void read_cb(evutil_socket_t fd, short what, void* arg) {
  17. // 读管道
  18. char buff[1024] = {0};
  19. int len = read(fd, buff, sizeof(buff));
  20. printf("read event : %s \n", what & EV_READ ? "YES" : "NO");
  21. printf("data len = %d, buff = %s\n", len, buff);
  22. sleep(1);
  23. }
  24. int main(int argc, char* argv[])
  25. {
  26. unlink("myfifo");
  27. // 创建有名fifo
  28. int res = mkfifo("myfifo", 0664);
  29. if (res == -1) {
  30. perror("mkfifo error\n");
  31. exit(1);
  32. }
  33. // 打开fifo
  34. int fd = open("myfifo", O_RDONLY | O_NONBLOCK); // 非阻塞只读
  35. if (fd == -1) {
  36. perror("open error\n");
  37. exit(1);
  38. }
  39. // 创建event_base
  40. struct event_base* base = event_base_new();
  41. // 创建事件 EV_PERSIST是持续读
  42. struct event* ev = event_new(base, fd, EV_READ | EV_PERSIST, read_cb, NULL);
  43. // struct event* ev = event_new(base, fd, EV_READ, read_cb, NULL);
  44. // 添加事件
  45. event_add(ev, NULL);
  46. // 事件循环
  47. event_base_dispatch(base); // while (1) { epoll }
  48. // 释放资源
  49. event_free(ev);
  50. event_base_free(base);
  51. close(fd);
  52. return 0;
  53. }

写操作

  1. /*************************************************************************
  2. > File Name: mywrite.c
  3. > Author: Winter
  4. > Created Time: 2022年02月18日 星期五 21时24分04秒
  5. ************************************************************************/
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <unistd.h>
  10. #include <pthread.h>
  11. #include <event2/event.h>
  12. #include <fcntl.h>
  13. // 回调函数
  14. void write_cb(evutil_socket_t fd, short what, void* arg) {
  15. // 写管道
  16. char buff[1024] = {0};
  17. static int num = 0;
  18. sprintf(buff, "hello world - %d", num++);
  19. write(fd, buff, strlen(buff) + 1);
  20. sleep(1);
  21. }
  22. int main(int argc, char* argv[])
  23. {
  24. // 与myread.c配套,但是要先打开myread程序
  25. // 打开管道
  26. int fd = open("myfifo", O_WRONLY | O_NONBLOCK);
  27. if (fd == -1) {
  28. perror("open error\n");
  29. exit(1);
  30. }
  31. // 创建event_base
  32. struct event_base* base = event_base_new();
  33. // 创建写事件 EV_PERSIST是持续写
  34. struct event* ev = event_new(base, fd, EV_WRITE | EV_PERSIST, write_cb, NULL);
  35. // struct event* ev = event_new(base, fd, EV_WRITE, write_cb, NULL);
  36. // 添加事件
  37. event_add(ev, NULL);
  38. // 事件循环
  39. event_base_dispatch(base);
  40. // 释放资源
  41. event_free(ev);
  42. event_base_free(base);
  43. close(fd);
  44. return 0;
  45. }

测试

 这里只测试了带有EV_PERSIST参数的event_new函数。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/742723
推荐阅读
相关标签
  

闽ICP备14008679号