本篇简单记录了libevent的安装过程及基础的先进先出管道Demo,其中demo来自这篇博客,安装过程在这篇博客

实验环境

  • 系统:Ubuntu 18.04.3
  • libevent版本:libevent-2.1.11-stable

libevent安装

  • libevent官网下载压缩包并解压;
  • 进入libevent目录,依次执行:
sunminming@sunminming:~/libevent-2.1.11-stable$ ./configure
sunminming@sunminming:~/libevent-2.1.11-stable$ make
sunminming@sunminming:~/libevent-2.1.11-stable$ sudo make install

    这之后应该能在/usr/local/lib目录下找到libevent相关的动态库;

  • 将动态库链接到/usr/lib/目录下:
sunminming@sunminming:/usr/local/lib$ ln -s libevent-2.1.so.7 /usr/lib/libevent-2.1.so.7
  • 最后执行ldconfig命令。

先进先出管道Demo

FIFO Demo由两个进程(write和read)组成,具体的代码如下:

  • read_fifo.c
//read_fifo.c
#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>
//read callback function
void read_callback(evutil_socket_t fd, short what, void* arg)
{
//read the fifo pipe
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?"Y":"N");
}
int main(int argc, const char* argv[])
{
//construct and open a fifo pipe
unlink("myfifo");
mkfifo("myfifo", 0664);
int fd = open("myfifo", O_RDONLY|O_NONBLOCK);
if(fd == -1)
{
perror("open error");
exit(1);
}
//read from pipr
struct event_base* base = NULL;
base = event_base_new();
//construct a event
struct event* ev = NULL;
ev = event_new(base, fd, EV_READ, read_callback, NULL);
//add event
event_add(ev, NULL);
//event loop
event_base_dispatch(base);
//free resource
event_free(ev);
event_base_free(base);
close(fd);
return 0;
}
  • write_fifo.c
    //write_fifo.c
#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>
//callback function
void write_callback(evutil_socket_t fd, short what, void *arg)
{
//write into pipe
char buf[1024] = {0};
static int num = 666;
sprintf(buf, "hello, world == %d\n", num);
write(fd, buf, strlen(buf)+1);
}
int main(int argc, const char* argv[])
{
//open the fifo file
int fd = open("myfifo", O_WRONLY|O_NONBLOCK);
if(fd == -1)
{
perror("open error");
exit(1);
}
//construct a event_base
struct event_base* base = NULL;
base = event_base_new();
//construct a event
struct event* ev = NULL;
ev = event_new(base, fd, EV_WRITE, write_callback, NULL);
//add event
event_add(ev, NULL);
//event loop
event_base_dispatch(base);
//free resource
event_free(ev);
event_base_free(base);
close(fd);
return 0;
}
  • 分别编译writer.c 及 read.c:
    sunminming@sunminming:~/libevent/fifo$ gcc write_fifo.c -o write -levent
sunminming@sunminming:~/libevent/fifo$ gcc read_fifo.c -o read -levent
  • 先运行read,在运行write,结果应如下:
    sunminming@sunminming:~/libevent/fifo$ ./read
data len = 21, buf = hello, world == 666
read event: Y

libevent相关函数

本节简单介绍上一节中几个libevet函数的抽象功能,不涉及函数源码。

  • struct event_base* event_base_new(void):

    这个函数是适用libevent库最先需要调用的,返回一个event_base结构体。event_base结构体是整个libevent的基石,负责跟踪每个事件的状态,哪个事件处于挂起状态(pending)等待唤醒,哪个事件处于活动状态(active)。

  • struct event* event_new(struct event_base* base,

                evutil_socket_t fd,

                short events,

                event_callback_fn callback,

                void* callback_arg):

    当程序需要对某个文件描述符进行监控时,首先需要调用event_new()函数来创造一个event结构体。在libevent的官网中特别强调,event结构体是定义在堆中的,这是由于需要在任何函数中都能监控每个事件。参数列表如下:

    • struct event_base* base 这个事件属于(官网上的用词是"attached")event_base结构体;
    • evutil_socket_t fd 被监视的文件描述符或者信号等;
    • short events 需要监控的具体事件,如上文中的EV_WRITE表示文件描述符可写时,EV_READ表示文件描述符可读时,触发该事件;
    • event_callback_fn callback 当事件触发时调用的回调函数;
    • callback_arg 传递给回调函数callbakck的参数,值得注意的是,传递给callback函数的参数一共三个:事件描述符fd、触发的具体事件events及该参数callback_arg
  • int event_add(struct event* ev, const struct timeval *timeout):

    创建event结构体之后,调用event_add()来将event对象加入挂起事件列表。之后调用该函数之后,参数列表中的ev才能在事件发生时被触发。参数列表如下:

    • struct event* ev 监控的事件;
    • const struct timeval *timeout:对于加入的事件的最大等待时间,若为NULL则一直等待。

      返回0表示调用成功,-1表示失败。
  • int event_base_dispatch(struct event_base* base):

    最后开始等待事件被触发,一直会持续到没有任何事件属于base或等待时间结束(默认情况下,一个事件只会被触发一次)。参数列表如下:

    • struct event_base* base 开始等待的base结构体,其中属于其的事件会处于挂起状态等待被触发到活动状态。

最新文章

  1. 经典网页设计:20个与众不同的国外 HTML5 网站
  2. C#学习笔记-----C#枚举中的位运算权限分配
  3. twitter storm源码走读之2 -- tuple消息发送场景分析
  4. win7系统安装
  5. 关于IE的兼容模式
  6. Swift实战-QQ在线音乐(第一版)
  7. 使用API创建AR 贷项通知单
  8. 使用r.js来打包模块化的javascript文件
  9. Codeforces Round #431 (Div. 1)
  10. Vue的土著指令和自定义指令
  11. linux的时间问题
  12. [Android] Android Butterknife 8.8.1 在 Activity 和 Fragment 、 Adapter 中的使用
  13. AltiumDesigner 查找相似对象
  14. 第19月第8天 斯坦福大学公开课机器学习 (吴恩达 Andrew Ng)
  15. ssh config配置
  16. 4K电视与4K显示器的选择
  17. HDU1253 胜利大逃亡(BFS) 2016-07-24 13:41 67人阅读 评论(0) 收藏
  18. 【原创】Qt 使用ODBC driver 连接SQL Server
  19. IDEA配置maven中央库
  20. hadoop中使用hprof工具进行性能分析

热门文章

  1. 基于串口的SD_card系统
  2. MD5加密实现方法
  3. Newtonsoft.Json使用技巧
  4. GitHub 上受欢迎的 Android UI Library整理
  5. laravel在使用Composer安装插件时要求输入授权用户名密码解决办法
  6. spring data jpa hql动态查询案例
  7. VirtualBox安装Ubutu出错
  8. 基于vue+springboot+docker网站搭建【二】搞定服务器
  9. Js中replace替换所有*
  10. Django框架(二)-- 基本配置:app注册、模板配置、静态文件配置、数据库连接配置post和get