libevent--快速入门

小说:米多多平板赚钱靠谱吗作者:侯华公安更新时间:2019-03-23字数:52198

libevent--快速入门


libevent--快速入门

一.简介

libevent是一个c语言写的事件驱动库,轻量级,专注于网络,跨平台特性好,支持多种 I/O 多路复用.支持I/O,定时器和信号等事件,允许设置注册事件优先级.

二.基本使用场景和事件流程

(1)初始化事件根基(槽)

struct event_base *event_base_new(void);
struct event_base *event_init(void);
  • event_base_new()函数分配并且返回一个新的具有默认设置的event_base.
  • event_init() 会调用event_base_new()创建一个event_base,并以此初始化一个全局的变量current_base .

例:

struct event_base *base = event_init();

(2)初始化事件event,设置回调函数和关注的事件,并关联对应的事件根基(槽)event_base

typedef void (*event_callback_fn)(evutil_socket_t, short, void*);

struct event *event_new(struct event_base *, evutil_socket_t, short, 
                        event_callback_fn, void *);

int event_assign(struct event *, struct event_base *, evutil_socket_t, short, event_callback_fn, void *);

void event_set(struct event *ev, int fd, short events, 
               event_callback_fn, void *arg);
void event_base_set(struct event_base *,struct event*);
  • event_assign()的作用就是把给定的event类型对象的每一个成员赋予一个指定的值。

  • event_new()的实现其实是间接的调用的event_assign(),首先调用mm_malloc分配一块内存,然后调用event_assign来给event类型的对象各个成员赋值。

  • event_set() 使用指定的句柄、关注的事件、事件发生时的回调函数、回调函数的额外参数,初始化设置struct event结构对象,绑定到全局current_base,设置此event结构对象的优先级,默认为current_base中总有限级数的一半

  • event_base_set() 将事件绑定到事件根基,即设置event从属的event_base,指明event注册到哪个event_base实例上

例:

//SIGINT 信号事件初始化
//假定已创建事件根基struct event_base *base 
//方式一:
struct event sigint_ev;
event_assign(&sigint_ev,base,SIGINT, EV_SIGNAL | EV_PERSIST,sigint_cb,NULL);
//方式二:
struct event sigint_ev ;
event_set(&sigint_ev, SIGINT, EV_SIGNAL | EV_PERSIST, sigint_cb, NULL);
event_base_set(base, &sigint_ev);
//方式三:
struct event *sigint_ev;
sigint_ev = event_new(base,SIGINT,EV_SIGNAL | EV_PERSIST, sigint_cb, NULL);
//方式四:
struct event* sigint_ev = (struct event*)malloc(sizeof(struct event));
//sigint_ev检测非空和置零后,用event_assign 或者event_set + event_base_set 初始化事件.

定时器事件:

#define evtimer_set(ev, cb, arg)    event_set(ev, -1, 0, cb, arg)

信号事件:

#define evsignal_new(base,signum,cb,arg) 
    event_new(base,signum,EV_SIGNAL|EV_PERSIST,cb,arg)

(3)添加事件,将事件变成未决态,即,将event加入到event_base中,等待监听

void event_add(struct event* ,struct timeval *);

(4)程序进入无限循环,事件根基event_base开始工作,对注册的event进行监听.若注册的事件的对应事件类型触发,或者超时,会自动触发event对应的回调函数执行

void event_base_dispatch(struct event_base *);
void event_base_loop(struct event_base *,int );

三.入门例子:

文件:test.c

编译:

gcc -o test test.c -levent

代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <malloc.h>
#include <event.h>
#include <sys/time.h>
#include <signal.h>
#include <string.h>
#define BUF_SIZE 1024

typedef struct{
    struct event *ev;
    char *buf;
    struct timeval *tv;
}rw_st;

void wr_cb(int fd, short event, void *arg);
void rd_cb(int fd, short event, void *arg);

struct event_base *base = NULL;
//定时事件
struct timeval tv;
struct event time_ev;
void time_cb(int fd, short event, void *arg)
{
    printf("time_cb : 5s timer wakeup
");
    event_add(&time_ev,&tv);
}

//标准输入 读事件
//输入一行,把读事件删掉,添加写事件
void rd_cb(int fd,short event, void *arg)
{
    if(event & EV_TIMEOUT){
        printf("io read time out(2s)!
");
        return ;
    }
    rw_st* rd_st = (rw_st*)arg;
    int len = read(fd, rd_st->buf, BUF_SIZE);
    rd_st->buf[len-1] = "0";
    printf("rd_cb (stdin): %s 
",rd_st->buf);
    
    event_del(rd_st->ev);
    event_set(rd_st->ev, STDOUT_FILENO,  EV_WRITE | EV_PERSIST,
                    wr_cb,(void*)rd_st);
    event_add(rd_st->ev,NULL);
}

//标准输出 写事件
//输出,把写事件删掉,添加读事件,边写边读
void wr_cb(int fd, short event, void *arg)
{
    rw_st *wr_st = (rw_st*)arg;
    printf("wr_cb (stdout): %s
",wr_st->buf);
    memset(wr_st->buf,0,BUF_SIZE);
    event_del(wr_st->ev);
    event_set(wr_st->ev, STDIN_FILENO, EV_READ | EV_PERSIST,
                    rd_cb, (void*)wr_st);
    event_add(wr_st->ev,wr_st->tv);
}

//SIGINT 信号事件
void sigint_cb(int fd, short event, void *arg)
{
    struct timeval tv_1s = {1,0};
    printf("SIGINT : EXIT IN 1s
");
    event_base_loopexit(base,&tv_1s);
}

//SIGHUB 信号事件
void sighup_cb(int fd, short event, void *arg)
{
    printf("SIGHUP: EXIT AT ONCE
");
    event_base_loopbreak(base);
}

int main()
{
    printf("pid = %ld
",getpid());
    base = event_init();
    //定时器
    tv.tv_sec = 5;
    tv.tv_usec = 0;
    evtimer_set(&time_ev, time_cb, NULL);//一次性,默认全局的current_base
// event_set(&time_ev,-1,0,time_cb,NULL);

//  event_base_set(base, &time_ev);  //可省,在这里current_base等同base
    event_add(&time_ev,&tv);

    //io 读事件  指针 event_new
    char buf[1024] = {0};
    struct timeval io_tv = {2,0};
    rw_st *rd_st = (rw_st*)malloc(sizeof(rw_st));
    memset(rd_st,0,sizeof(rw_st));

    struct event *io_ev = (struct event*)malloc(sizeof(struct event));
    memset(io_ev,0,sizeof(struct event));
    
    rd_st->ev = io_ev;
    rd_st->buf = buf;
    rd_st->tv = &io_tv;
    event_assign(rd_st->ev,base,STDIN_FILENO,
                    EV_TIMEOUT | EV_READ | EV_PERSIST,rd_cb,(void*)rd_st);
    event_add(rd_st->ev,rd_st->tv);

    //SIGINT 信号事件
    struct event sigint_ev;

    event_assign(&sigint_ev,base,SIGINT, EV_SIGNAL | EV_PERSIST,sigint_cb,NULL);
//  event_set(&sigint_ev, SIGINT, EV_SIGNAL | EV_PERSIST, 
//                                          sigint_cb, NULL);
    //event_base_set(base, &sigint_ev);
    event_add(&sigint_ev,NULL);
  
//  struct event *sigint_ev = event_new(base,SIGINT,
//           EV_SIGNAL | EV_PERSIST, sigint_cb, NULL);
//  event_add(sigint_ev,NULL);

    //SIGHUP 信号事件  
    //测试: $ kill -SIGHUP pid
    struct event *sighup_ev;
    sighup_ev = evsignal_new(base, SIGHUP, sighup_cb, NULL);    
    event_add(sighup_ev,NULL);

    event_base_dispatch(base);
    //event_base_loop(base,0);
    
    event_free(sighup_ev);
    event_base_free(base);
    free(rd_st);

    printf("EXIT
");
    return 0;
}

原创所有,转载注明原文出处.若有错误,欢迎指正,共同学习,谢谢!

当前文章:http://leetaemin.cn/content/2019-01/26/content_97349.html

发布时间:2019-03-23 02:03:25

有什么软件可以邀请好友注册支付宝 找兼职小时工上午 招兼职快的语言 哪些赚钱软件里有好评任务 米赚众测 什么手机软件可以赚钱 可以做任务赚钱的app 返利网首页淘宝 有人有几十台电脑都在干嘛挣钱 快手西瓜多少钱一个

84734 33255 74793 97983 49187 5323391510 57931 12386

我要说两句: (0人参与)

发布