1、概述

libevent是一个C语言编写的、轻量级开源高性能事件通知库。作为底层网络库,已经被广泛应用(如:memcached、Vomit、Nylon、Netchat等)。主要有以下几个亮点:

  • 事件驱动(event-driven)
  • 高性能
  • 轻量级,专注网络。
  • 源码精炼,易读
  • 跨平台
  • 支持多种I/O多路复用技术,如epoll、poll、dev/poll、select、kqueue等。
  • 支持I/O,定时器和信号等事件
  • 注册事件优先级

官网地址:https://libevent.org/

2、框架介绍

1)event_base 创建与释放

// 创建event_base
struct event_base* base = event_base_new()
// 释放event_base_free
event_base_free(struct event_base* base);

2)事件创建与释放

调用event_new()函数之后,新事件处于已初始化和非未决状态。

// 创建新事件
struct event *event_new(
struct event_base *base,
evutil_socket_t fd, - // 文件描述符 - int **底层是对epollin与epollout的封装**
short what,
event_callback_fn cb, // 事件的处理回调函数
void *arg //回调函数传参
);
// 事件的处理回调函数
typedef void (*event_callback_fn)(evutil_socket_t, short, void *);
// short what
#define EV_TIMEOUT 0x01 // 已淘汰(忽略)
#define EV_READ 0x02
#define EV_WRITE 0x04
#define EV_SIGNAL 0x08 //libevent封装了信号相关的操作 SIGNAL
#define EV_PERSIST 0x10 // 持续触发
#define EV_ET 0x20 // 边沿模式

最后需要event_free进行释放。

// 创建event_free
void event_free(struct event *event);

3)event_add()函数

创建事件之后,再将其添加到event_base之前,实际上是不能对其做任何操作的。所以需要使用event_add将事件添加到event_base上去。此时状态由非未决事件->未决事件。

// event_add
int event_add(
struct event *ev,
const struct timeval *tv
);

函数调用成功返回0,失败返回-1。

4)event_base_dispatch()函数

最后,使用event_base_dispatch函数添加事件循环。

// event_base_dispatch(简化版event_base_loop())
int event_base_dispatch(struct event_base* base);
//等同于没有设置标志的 event_base_loop ( )
//将一直运行,直到没有已经注册的事件了,或者调用 了event_base_loopbreak()或者 event_base_loopexit()为止

5)event_base_loop()函数

// event_base_loop()
int event_base_loop(struct event_base *base, int flags);
//正常退出返回0, 失败返回-1 //flages
#define EVLOOP_ONCE 0x01
//事件只会被触发一次
//事件没有被触发, 阻塞等
#define EVLOOP_NONBLOCK 0x02
//非阻塞 等方式去做事件检测
//不关心事件是否被触发了
#define EVLOOP_NO_EXIT_ON_EMPTY 0x04
//没有事件的时候, 也不退出轮询检测

6)event_base_loopexit()函数

执行当前后退出。

//如果 event_base 当前正在执行激活事件的回调 ,它将在执行完当前正在处理的事件后立即退出
int event_base_loopexit(
struct event_base *base,
const struct timeval *tv
);
//参数struct timeval *tv
struct timeval {
long tv_sec;
long tv_usec;
};

7)event_base_loopbreak()函数

立即退出循环

//让event_base 立即退出循环
int event_base_loopbreak(struct event_base *base);
//返回值: 成功 0, 失败 -1

8)Demo

用例(采用fifo通信方式,不带缓冲区操作)

/*************************************************************************
> File Name: read_fifi.c
> Author:
> Mail:
> Created Time: 2021年04月19日 星期一 10时24分57秒
************************************************************************/ #include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<string.h>
#include<fcntl.h>
#include<event2/event.h> //读取回调函数
void read_cb(evutil_socket_t fd,short what,void *arg)
{
//读管道
char buf[1024] = {0};
int len = read(fd,buf,sizeof(buf));
printf("data len = %d ,buf = %s\n" ,len,buf);
printf("read event: %s\n",what &EV_READ ? "Yes":"No");//对what 类型对判断
} int main()
{
unlink("libeventfifo");
//创建有名管道
mkfifo("libeventfifo",0664);
//open File int fd = open("libeventfifo",O_RDONLY | O_NONBLOCK); if(fd == -1)
{
perror("open error");
exit(1);
}
//读管道
struct event_base* base = NULL;
base = event_base_new(); //创建事件
struct event* ev = NULL;
ev = event_new(base,fd,EV_READ | EV_PERSIST,read_cb,NULL); // 添加事件
event_add(ev,NULL); //事件循环
event_base_dispatch(base); //释放资源
event_free(ev); event_base_free(base);
close(fd);
return 0 ;
}
/*************************************************************************
> File Name: write_fifi.c
> Author:
> Mail:
> Created Time: 2021年04月19日 星期一 10时24分43秒
************************************************************************/ #include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<string.h>
#include<fcntl.h>
#include<event2/event.h> //读取回调函数
void write_cb(evutil_socket_t fd,short what,void *arg)
{
//写管道
char buf[1024] = {0};
int len = read(fd,buf,sizeof(buf));
static int num = 999;
sprintf(buf,"hello world == %d \n" ,num);
write(fd,buf,strlen(buf)+1);
} int main()
{
int fd = open("libeventfifo",O_WRONLY | O_NONBLOCK);
if(fd == -1)
{
perror("open error");
exit(1);
}
struct event_base * base = NULL;
base = event_base_new(); struct event* ev = NULL; 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 ;
}

用gcc 分别编译文件:

gcc write_fifi.c -o write -levent
gcc read_fifi.c -o read -levent

最后分别执行程序:

./read
./write

libevent网络库的更多相关文章

  1. Linux 初识Libevent网络库

    初识Libevent libevent是用c写的高并发网络io库,只要有文件描述符,就都可使用libevent. libevent使用回调函数(callback) . 有了libevent,网络编程我 ...

  2. 以libevent网络库为引:网络通信和多线程

    1. windows下编译及使用libevent  http://www.cnblogs.com/luxiaoxun/p/3603399.html 2.  <<libevent学习资料&g ...

  3. libevent 网络库安装

    ./configure prefix=/tools/libevent make sudo make install

  4. [原]网络库libevent在Visual Studio中的使用方法

    libevent是一个事件触发的网络库,适用于windows.linux.bsd等多种平台,内部使用select.epoll.kqueue等系统调用管理事件机制.著名分布式缓存软件memcached也 ...

  5. 轻量级网络库libevent概况

    Libevent is a library for writing fast portable nonblocking IO. libevent是一个为编写快速可移植的非阻塞IO程序而设计的. lib ...

  6. 轻量级网络库libevent初探

    本文是关于libevent库第一篇博文,主要由例子来说明如何利用该库.后续博文再深入研究该库原理. libevent库简介 就如libevent官网上所写的“libevent - an event n ...

  7. 开源网络库ACE、Boost的ASIO、libevent、libev、ZeroMQ

    开源C/C++网络库:ACE          C++语言 跨平台Boost的ASIO  C++语言 跨平台libevent     C语言   主要支持linux,新版增加了对windows的IOC ...

  8. 网络库libevent、libev、libuv对比

    Libevent.libev.libuv三个网络库,都是c语言实现的异步事件库Asynchronousevent library). 异步事件库本质上是提供异步事件通知(Asynchronous Ev ...

  9. Windows下libevent C++封装类实现(为什么要使用封装好的网络库?)

    题记 windows平台下对于服务器高并发的网络模型选型中,使用libevent是个不错的选择. 本文的背景基于:国内博客对于libevent大多介绍linux实现,大多是c语言的实现,Windows ...

随机推荐

  1. 1122 机器人走方格 V4

    1122 机器人走方格 V4 基准时间限制:1 秒 空间限制:131072 KB  四个机器人a b c d,在2 * 2的方格里,一开始四个机器人分别站在4个格子上,每一步机器人可以往临近的一个格子 ...

  2. Codeforces 339B:Xenia and Ringroad(水题)

    time limit per test : 2 seconds memory limit per test : 256 megabytes input : standard input output ...

  3. CS学习资料百度云链接

    CS学习资料百度云链接 [0]Springboot微服务开发天气预报系统视频教程https://pan.baidu.com/s/1joz7flyztCq8oklBlsz8dQ提取密码:cpz7 [1] ...

  4. 编写Java程序,利用List维护用户信息

    返回本章节 返回作业目录 需求说明: 将新增的用户信息添加到List集合. 用户信息包括用户编号.姓名和性别. 按照姓名和性别查找用户信息. 实现思路: 创建类UserInfo,在该类中定义3个Str ...

  5. 关于linux的一点好奇心(一):linux启动过程

    一直很好奇,操作系统是如何工作的?我们知道平时编程,是如何让代码跑起来的,但那些都是比较高层次的东西.越往后,你会越觉得,像是空中楼阁,或者说只是有人帮你铺平了许多道理,而你却对此一无所知. 1. 操 ...

  6. XML解析和创建的JAXB方式

    1.说明 JAXB是Java Architecture for XML Binding, 即用于XML绑定的Java体系结构, JAXB作为JDK的一部分, 能便捷地将Java对象与XML进行相互转换 ...

  7. 关于PaddleSharp GPU使用 常见问题记录

    在安装NVIDIA驱动过程中遇到一系列问题,记录如下! 附上PaddleSharp地址,大家喜欢可以关注 根据PaddleSharp官方说明需要安装驱动如下 CUDA 和 cuDNN 和 Tensor ...

  8. cpu负载

    查看cpu负载,我们经常会使用top,或者是uptime命令 但是这只能看到cpu的总体的负载情况.如果我们想看cpu每个核心的负载情况是看不到的. 所以我们可以用mpstat命令 服务器一共32核心 ...

  9. .NET 云原生架构师训练营(组合模式)--学习笔记

    目录 引入 组合模式 源码 引入 在上一篇执行 _connectionDelegate 之后,HttpConnectionMiddleware 处理请求 return connection.Proce ...

  10. Drupal 8 环境搭建部署

    运行环境安装 系统:Ubuntu Server 16.04  (ubuntu-16.04.4-server-amd64.iso) Web服务器:Apache / 2.4.18 数据库:Mysql / ...