• libevent笔记1:安装及DEMO


    本篇简单记录了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
    ", len, buf);
        printf("read event: %s
    ", 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
    ", 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结构体,其中属于其的事件会处于挂起状态等待被触发到活动状态。
  • 相关阅读:
    UE4——查找指定类型或名称的Actor对象
    unity 替换渲染 ( Rendering with Replaced Shaders )
    浅谈Java消息服务(JMS)规范与ActiveMQ实现
    初识WebSocket(一)--WebSocket介绍与实现简单web群聊
    IDEA编译器常用快捷键总结
    初识Docker(二)--Docker常用命令
    初识Docker(一)--Docker介绍及安装
    自定义hexo博客melody主题标签页title
    vue+springboot+el-uolpad组件实现文件上传
    判断一个数是否为2的整数次幂
  • 原文地址:https://www.cnblogs.com/sunminming/p/11815420.html
Copyright © 2020-2023  润新知