libevent网络库
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网络库的更多相关文章
- Linux 初识Libevent网络库
初识Libevent libevent是用c写的高并发网络io库,只要有文件描述符,就都可使用libevent. libevent使用回调函数(callback) . 有了libevent,网络编程我 ...
- 以libevent网络库为引:网络通信和多线程
1. windows下编译及使用libevent http://www.cnblogs.com/luxiaoxun/p/3603399.html 2. <<libevent学习资料&g ...
- libevent 网络库安装
./configure prefix=/tools/libevent make sudo make install
- [原]网络库libevent在Visual Studio中的使用方法
libevent是一个事件触发的网络库,适用于windows.linux.bsd等多种平台,内部使用select.epoll.kqueue等系统调用管理事件机制.著名分布式缓存软件memcached也 ...
- 轻量级网络库libevent概况
Libevent is a library for writing fast portable nonblocking IO. libevent是一个为编写快速可移植的非阻塞IO程序而设计的. lib ...
- 轻量级网络库libevent初探
本文是关于libevent库第一篇博文,主要由例子来说明如何利用该库.后续博文再深入研究该库原理. libevent库简介 就如libevent官网上所写的“libevent - an event n ...
- 开源网络库ACE、Boost的ASIO、libevent、libev、ZeroMQ
开源C/C++网络库:ACE C++语言 跨平台Boost的ASIO C++语言 跨平台libevent C语言 主要支持linux,新版增加了对windows的IOC ...
- 网络库libevent、libev、libuv对比
Libevent.libev.libuv三个网络库,都是c语言实现的异步事件库Asynchronousevent library). 异步事件库本质上是提供异步事件通知(Asynchronous Ev ...
- Windows下libevent C++封装类实现(为什么要使用封装好的网络库?)
题记 windows平台下对于服务器高并发的网络模型选型中,使用libevent是个不错的选择. 本文的背景基于:国内博客对于libevent大多介绍linux实现,大多是c语言的实现,Windows ...
随机推荐
- MySQL 的性能
影响数据库性能的因素: SQL 脚本 数据库服务器配置 网卡流量 磁盘 IO 大表操作 大事务操作 存储引擎 数据库参数配置 1. SQL 脚本 超高的 QPS 和 TPS TPS:英文全称是 Tra ...
- 数据结构作业——P53算法设计题(6):设计一个算法,通过一趟遍历确定长度为n的单链表中值最大的结点
思路: 设单链表首个元素为最大值max 通过遍历元素,与最大值max作比较,将较大值附给max 输出最大值max 算法: /* *title:P53页程序设计第6题 *writer:weiyuexin ...
- Chapter 20 Treatment-Confounder Feedback
目录 20.1 The elements of treatment-confounder feedback 20.2 The bias of traditional methods 20.3 Why ...
- 求最大公因数和最小公倍数(C++实现)
求两个正整数之最大公因子的算法(辗转相除法) 最大公约数是指能同时整除它们的最大正整数 基本原理:两个数的最大公约数等于它们中较小的数和两数之差的最大公约数. 就如有 a = 122, b = 54 ...
- [CodeLife]记毕业后第一份工作
记毕业后第一份工作与公司 写在前面--前言 已然临近21年五月,很快又是一年毕业季了,公司里来了应届的新人,忽然才意识到自己已经不是公司年龄最小的了((笑~).依稀还记得两年前,自己也是如他们那般青涩 ...
- 如何使用Navicat连接宝塔面板上安装的mysql数据库?
运行环境描述 阿里云ECS 系统:CentOS Linux 7.4.1708 (Core) 宝塔面板: 6.9.0 数据库:MySQL 5.7.19 Navicat 远程连接 Navicat报错信息: ...
- 《MySQL数据操作与查询》- 返校复习课练习题,创建数据库user_system,创建数据表user及user_ext
一.其它(共18题,100分) 1.创建数据库user_system CREATE DATABASE user_system 2.在数据库user_system中创建数据表user及user_ext, ...
- 编写Java程序,使用抽象类和抽象方法构建不同动物的扑食行为,抽象类设计
返回本章节 返回作业目录 需求说明: 不同的动物都有进食的行为,但是在进食前需要捕获到食物后才可以进食. 要求定义一个抽象的动物类,该类中有一个抽象的捕食方法,和一个非抽象的进食方法.在进食方法中调用 ...
- 【03】SpringBoot2核心技术-核心功能—数据访问_单元测试_指标监控
3.数据访问(SQL) 3.1 数据库连接池的自动配置-HikariDataSource 1.导入JDBC场景 <dependency> <groupId>org.spring ...
- Git创建本地仓库
使用Git创建本地仓库, 可以记录文本文件变化, 这里以自己的文章为例, 利用TortoiseGit工具创建一个本地Git仓库. 1. 切换到需要创建仓库的目录下, 比如:D:\MyDoc\Devel ...