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. 菜鸟物流的运输网络(计蒜客复赛F)

    菜鸟物流有自己的运输网络,网络中包含 nn 个城市物流集散中心,和 mm 对城市之间的运输线路(线路是双向的).菜鸟物流允许淘宝卖家自行确定包裹的运输路径,但只有一条限制规则:不允许经过重复的城市.淘 ...

  2. BP网络简单实现

    目录 BP算法的简单实现 Linear 全连接层 ReLu MSELoss 交叉熵损失函数 BP算法的简单实现 """ BPnet 简易实现 约定输入数据维度为(N, i ...

  3. v75.01 鸿蒙内核源码分析(远程登录篇) | 内核如何接待远方的客人 | 百篇博客分析OpenHarmony源码

    子曰:"不学礼,无以立 ; 不学诗,无以言 " <论语>:季氏篇 百篇博客分析.本篇为: (远程登录篇) | 内核如何接待远方的客人 设备驱动相关篇为: v67.03 ...

  4. pod运行到指定node节点

    利用labels 1.一般来说都每个节点有自己特有的labels  比如 2.利用nodeSelector nodeSelector: kubernetes.io/hostname: master3 ...

  5. Microsoft HoloLens 开发(1): 搭建 HoloLens 开发环境

    1.硬件配置 64位 Windows 10 专业版, 企业版, or 教育版 (注: 家庭版不支持 Hyper-V 或者 HoloLens emulator) 64位 CPU 4核CPU (或者大于4 ...

  6. springboot + mybatis plus使用insert 语句并返回主键

    mapper文件 映射文件中在insert中设置useGeneratedKeys为true,keyProperty设置为主键名称 <insert id="addEmployees&qu ...

  7. Django_模型类详解(七)

    # 定义书籍模型类 class BookInfo(models.Model): btitle = models.CharField(max_length=20) # 书籍名称 bpub_date = ...

  8. frp + nginx 配置多人共用的http 内网穿透服务

    来源:简书   https://www.jianshu.com/p/c9d7527d607b 一. 前言 frp 是一个用Go语言开发的,可用于内网穿透的高性能的反向代理应用,支持 tcp, udp ...

  9. 详谈 Java工厂 ---工厂方法模式

    1.前言 有个场景,消费者需要付钱,有可能是使用支付宝.微信.银行卡,那么该怎么选择呢? 是不是想到了使用用if else判断?还是使用switch? 一个地方这样写还好,如果有很多这样的业务,难道都 ...

  10. JS 利用新浪接口通过IP地址获取当前所在城市

    <html xmlns="http://www.w3.org/1999/xhtml"><head runat="server">< ...