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. 【LeetCode】454. 4Sum II 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 字典 日期 题目地址:https://leetcod ...

  2. LeetCode1237找出给定方程的正整数解

    题目 给定方程f和值z,找出给定方程f(x,y)=z的正整数解x,y.f(x,y)关于x.y都是严格单调的. 题目保证 f(x, y) == z 的解处于 1 <= x, y <= 100 ...

  3. STC8A,STC8G,STC8H系列的IRC内部振荡源频率调节

    从STC15开始, 宏晶就在内置RC震荡源(内置时脉, 宏晶称之为IRC)这条路上越走越远. STC15这一代仅仅是"有", 精度和漂移差强人意. 从STC8开始对IRC的调节就越 ...

  4. mybatis 内部定义对象和集合

    mapper 配置文件中  引入两个重要的标签:association和collection标签.

  5. Oracle数据库安装Version12c

    1.安装规划 Oracle数据库版本: Linuxamd64_12102_database 12c Linux服务器系统: CentOS Linux release 7.5.1804 (Core) 6 ...

  6. 简单的制作ssl证书,并在nginx和IIS中使用

    2020年最后一篇博文收官,提前祝各位园友新年快乐 现在的后端开发,动不动就是需要https,或者说是需要ssl证书,既然没有正版的证书,那么我们只能自己制作ssl的证书了. 说明:证书的制作采用的是 ...

  7. linux 之 命令提示符设置

    linux 命令提示符设置实际就是设置环境变量PS1的值. 参数说明 \d 显示时间,星期 月 日 \h 显示简写主机名,如默认主机名 localhost \t 显示24小时制时间, HH:MM:SS ...

  8. Python_魔法属性和方法

    魔法属性 __doc__:表示类或方法的描述信息 __moudle__:表示当前操作对象的模块,当前模块时,显示__main__ __class__:表示当前操作对象的类型 __name__:表示类或 ...

  9. CentOS 7 把已登录的用户断开

    1. 查看登陆用户 [root@localhost ~]#  w 18:29:30 up 377 days, 8:44, 4 users, load average: 0.05, 0.12, 0.09 ...

  10. js中点击返回顶部

    window.scrollTo(0, 0);当点击返回顶部的时候调用这个方法即可 handleScrollTop(){ window.scrollTo(0, 0); }