c/c++:Libevent应用(Libevent介绍、 事件处理框架 - event_base、事件循环、事件、带缓冲区的事件、链接监听器)

 

目录

1. Libevent介绍

1.1 安装Libevent

 2. 事件处理框架 - event_base

2.1 event_base API函数

event_base和fork(进程)关系:

3. 事件循环

3.1 设置事件循环

3.2 终止事件循环

4. 事件

4.1 事件基本操作

事件的创建  event_new

事件的释放

事件的添加、删除

4.2 事件的优先级设置

例子:使用event实现有名管道的进程间通信myfifo

5. 带缓冲区的事件

概念理解:

创建/释放基于套接字的bufferevent     bufferevent_socket_new

在bufferevent上启动连接服务器函数  bufferevent_socket_connect

bufferevent读写缓冲区回调操作    bufferevent_setcb

禁用、启用缓冲区

操作bufferevent中的数据  bufferevent_write   bufferevent_read

6. 链接监听器

创建和释放evconnlistener

启用和禁用 evconnlistener

调整 evconnlistener 的回调函数

7. 例子:用event实现服务器和客户端tcp通信

服务器server代码:

客户端client代码:

8. 总结:

处理不带缓冲区的事件:

处理带缓冲区的事件:


 

1. Libevent介绍

Libevent 是一个用C语言编写的、轻量级的开源高性能事件通知库,主要有以下几个亮点:

  •   > - 事件驱动( event-driven),高性能;
  •   > - 轻量级,专注于网络;
  •   > - 源代码相当精炼、易读;
  •   > - 跨平台,支持 Windows、 Linux、 BSD(是Unix的衍生系统) 和 Mac OS;
  •   > - 支持多种 I/O 多路复用技术, epoll、 poll、 select 和 kqueue 等;
  •   > - 支持 I/O,定时器和信号等事件;
  •   > - 支持注册事件优先级。

 

1.1 安装Libevent

  • 下载地址: http://libevent.org/
  • 安装步骤 -> 源码安装的方式(终端打开下载目录)
          1. 可执行程序: configure
              ./configure         // 检测安装环境, 并且生成一个makefile文件
    
          2. 根据makefile中的构建规则编译源代码
              make     
    
          3. 安装
              sudo make install   //将得到可执行程序/动态库/静态库/头文件拷贝到系统目录

     

  • 动态库找不到问题解决:

  1. 通过find命令查找对应的库的位置
      find 搜索目录 -name "libevent.so"
          得到结果: /usr/local/lib/libevent.so
  2. 通过vi 打开/etc/ld.so.conf文件
      sudo /etc/ld.so.conf
      将/usr/local/lib/放到文件的最后一行, 保存
  3. 执行命令: sudo ldconfig
  
编译要加上动态库event  hello.c
  gcc hello.c -o hello -levent

 

 2. 事件处理框架 - event_base

使用 libevent函数之前需要分配一个或者多个 event_base 结构体。每个event_base 结构体持有一个事件集合,可以检测以确定哪个事件是激活的。每个 event_base 都有一种用于检测哪种事件已经就绪的 “方法”。 
 

2.1 event_base API函数

// 头文件
  #include <event2/event.h>
  // 操作函数
  struct event_base * event_base_new(void);          //创建事件处理框架
  void event_base_free(struct event_base * base);    //释放事件处理框架
  
  // 检查event_base的后端方法
  const char** event_get_supported_methods(void);
  const char *event_base_get_method(const struct event_base *base);

event_base和fork(进程)关系:

  1. 子进程创建成功之后, 父进程可以继续使用event_base
  2. 子进程中需要继续使用event_base需要用下面函数,重新初始化
int event_reinit(struct event_base* base);

例子:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <event2/event.h>

int main()
{
    // 1. 创建事件处理框架
    struct event_base* base = event_base_new();
    
    // 打印支持的IO转接函数
    const char** method = event_get_supported_methods();
    for(int i=0; method[i] != NULL; ++i)
    {
        printf("%s\n", method[i]);
    }
    printf("current method: %s\n", event_base_get_method(base));

    // 创建子进程
    pid_t pid = fork();
    if(pid == 0)
    {
        // 子进程中event_base也会被复制,在使用这个base时候要重新初始化
        event_reinit(base); 
    }

    // 2. 释放资源
    event_base_free(base);
    return 0;
}

 

3. 事件循环

event_base不停的检测委托的检测是实际是不是发生了, 如果发生了, event_base会调用对应的回调函数, 这个回调函数的用户委托检测事件的时候给的.
 

3.1 设置事件循环

如果委托了event_base检测某些事件, 不停的进行循环检测
结束检测时间: 所有要检测的事件都被触发, 并且处理完毕。

// 头文件
  #include <event2/event.h>
  
  // 操作函数
  #define EVLOOP_ONCE 			0x01
  #define EVLOOP_NONBLOCK 		0x02
  #define EVLOOP_NO_EXIT_ON_EMPTY 0x04

  int event_base_loop(struct event_base *base, int flags);
  	参数:
  		- base: 通过 event_base_new(void)得到的
  		- flags:
  			- EVLOOP_ONCE: 一直检测某个事件, 当事件被触发了, 停止事件循环
  			- EVLOOP_NONBLOCK: 非阻塞的方式检测, 当事件被触发了, 停止事件循环
  			- EVLOOP_NO_EXIT_ON_EMPTY: 一直进行事件检测, 如果没有要检测的事件, 不退出

  int event_base_dispatch(struct event_base* base); 	// 一般使用这个函数
  	参数:
  		- base: 通过 event_base_new(void)得到的

 

3.2 终止事件循环

// 头文件
  #include <event2/event.h>
  
  struct timeval {
  	long    tv_sec;                    
  	long    tv_usec;    // 微秒        
  };

  // 在 tv 时长之后退出循环, 如果这个参数为空NULL, 直接退出事件循环
  // 事件循环: 检测对应的事件是否被触发了
  // 如果事件处理函数正在被执行, 执行完毕之后才终止
  int event_base_loopexit(struct event_base * base, const struct timeval * tv);
  
// 马上终止
  int event_base_loopbreak(struct event_base * base);

 

4. 事件

4.1 事件基本操作

  • 事件的创建  event_new

  #include <event2/event.h>
  
//要检测事件   what:
  #define EV_TIMEOUT 	0x01
  #define EV_READ 	    0x02
  #define EV_WRITE 	    0x04
  #define EV_SIGNAL 	0x08
  #define EV_PERSIST 	0x10	// 修饰某个事件是持续触发的
  #define EV_ET 		0x20	// 边沿模式

//回调函数格式:
  typedef void (*event_callback_fn)(evutil_socket_t,short,void *);
  	参数:
  		- 第一个参数: event_new的第二个参数
  		- 第二个参数: 实际触发的事件
  		- 第三个参数: event_new的最后一个参数

// 创建事件
  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: 文件描述符, 检测这个fd对应的事件
  		- what: 监测fd的什么事件 
  		- cb: 回调函数, 当前检测的事件被触发, 这个函数被调用
  		- arg: 给回调函数传参
  • 事件的释放

#include <event2/event.h>
//
  • 6
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值