Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9043
  • 博文数量: 2
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-02 09:29
文章分类
文章存档

2013年(2)

我的朋友

分类: LINUX

2013-10-16 00:11:57

原文地址:libevent event 事件的机制 作者:anqiu1987

综述:

    libevent基本的操作单元就是event,每一个event代表一系列你感兴趣的状态,包括:
  •      一个正在读或者写的文件描述符
  •     一个变得可读或者可写的文件描述符(ET模式)
  •     超时
  •     系统信号的发生
  •     用户触发的信号
     每一个event有相似的生命周期, 当你建立了一个event,并把他绑定了一个event_base上面的时候,他就处于初始化完成状态,你可以add让它处于pending状态,当event处于pending状态,并且能够触发event的状态触发的时候(例如超时,或者文件状态改变),event就处于active状态,用户定义的callback就会被调用,如果event被设置成了persistent,他会继续等待触发,如果没有设置,他就不处于pending状态了。你也可以通过delete,使它处于非pending状态。

用法:

    新建和删除的api如下:
   

点击(此处)折叠或打开

  1. #define EV_TIMEOUT 0x01   //时间到了会调用函数
  2. #define EV_READ 0x02        //可以读
  3. #define EV_WRITE 0x04       //可以写
  4. #define EV_SIGNAL 0x08      //事件触发
  5. #define EV_PERSIST 0x10       //默认事件是触发一次,当指定此标志时,他会一直触发。可以调用event_del删除
  6. #define EV_ET 0x20

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

  8. struct event *event_new(struct event_base *base, evutil_socket_t fd,
  9.     short what, event_callback_fn cb,
  10.     void *arg);

  11. void event_free(struct event *event)
       event_new函数试着新建并且绑定一个event_base,what参数可以使用上边的列出的参数,如果fd是非负的,他就我们观察的读写的文件描述符,当触发的时候,libevent会调用cb指向的函数,把fd和所有被触发的event的一个位域,还有arg,作为参数。如果失败函数会返回NULL。
      生成之后,他处于初始化完成状态,如果我们想让它处于pending状态,我们需要调用event_add()函数。
      不管event处于pending或者初始化完成状态,我们都可以调用event_free,释放该结构。
     
       当你想把event自身,作为cb函数的参数的时候,因为我们还没构造出event,我们通过调用下面的函数作为event_new的arg参数:

点击(此处)折叠或打开

  1. void *event_self_cbarg()
    通过把fd传如负值,我们可以把event伪装成定时器的功能:
 

点击(此处)折叠或打开

  1. #define evsignal_add(ev, tv) \
  2.     event_add((ev),(tv))
  3. #define evsignal_del(ev) \
  4.     event_del(ev)
  5. #define evsignal_pending(ev, what, tv_out) \
  6.     event_pending((ev), (what), (tv_out))
     我们也可以注册系统signal:注意每个进程只能有一个event_base注册signal事件。

点击(此处)折叠或打开

  1. #define evsignal_new(base, signum, callback, arg) \
  2.     event_new(base, signum, EV_SIGNAL|EV_PERSIST, cb, arg)
  3. #define evsignal_add(ev, tv) \
  4.     event_add((ev),(tv))
  5. #define evsignal_del(ev) \
  6.     event_del(ev)
  7. #define evsignal_pending(ev, what, tv_out) \
  8.     event_pending((ev), (what), (tv_out))

    有时候我们把event放到一个结构体里面,在new这个结构体的时候不能调用event_new函数所以我们可以调用下面的函数,但是不建议这么做,这么变你已经固定了event的大小,在版本兼容上不太好

点击(此处)折叠或打开

  1. int event_assign(struct event *event, struct event_base *base,evutil_socket_t fd, short what,
  2.                  void (*callback)(evutil_socket_t, short, void *), void *arg)
    你可以调用下面的函数,使event处于pending状态和使它处于非pending状态:
  

点击(此处)折叠或打开

  1. int event_add(struct event *ev, const struct timeval *tv);
  2. int event_del(struct event *ev)
  你也可以只是删除制定event的时间触发器,而不影响他的IO。
  

点击(此处)折叠或打开

  1. int event_remove_timer(struct event *ev)

  你也可以设置event的优先级,当事件触发的时候,libevent会优先调用高优先级的事件,
  

点击(此处)折叠或打开

  1. int event_priority_set(struct event *event, int priority)
   你可以调用下面的一系列函数来获取,event结构中的数据:
 

点击(此处)折叠或打开

  1. evutil_socket_t event_get_fd(const struct event *ev);              //获取fd
  2. struct event_base *event_get_base(const struct event *ev);  //获取base
  3. short event_get_events(const struct event *ev);                      //获取event flag
  4. event_callback_fn event_get_callback(const struct event *ev);
  5. void *event_get_callback_arg(const struct event *ev);
  6. int event_get_priority(const struct event *ev);

  7. void event_get_assignment(const struct event *event,
  8.         struct event_base **base_out,
  9.         evutil_socket_t *fd_out,
  10.         short *events_out,
  11.         event_callback_fn *callback_out,
  12.         void **arg_out)
    如果你想定义一个只想执行一次的event,并且让libevent负责他的消亡,你可以调用下面的函数,但是他不支持EV_SIGNAL和EV_PERSIST
   

点击(此处)折叠或打开

  1. int event_base_once(struct event_base *, evutil_socket_t, short,
  2.   void (*)(evutil_socket_t, short, void *), void *, const struct timeval *)
    
   最后你可以主动触发一个事件,无论他处于pending状态与否
  

点击(此处)折叠或打开

  1. void event_active(struct event *ev, int what, short ncalls)
 


例子:

   gcc test.cpp -levent

点击(此处)折叠或打开

  1. #include<event2/event.h>
  2. #include<stdio.h>
  3. void cb_func(evutil_socket_t fd, short what, void *arg)
  4. {
  5.     printf("get alerted !");
  6. }
  7. int main()
  8. {
  9.     struct event_base * base;
  10.     struct event *ev1,*ev2;
  11.     struct timeval five_seconds = {5,0};
  12.     base = event_base_new();
  13.     if(!base)
  14.         return 0;
  15.     ev1 = event_new(base, -1, EV_TIMEOUT,cb_func,NULL);
  16.     ev2 = event_new(base, -1, EV_TIMEOUT, cb_func,NULL);
  17. // event_add(ev1,&five_seconds);
  18. // struct timeval five_seconds1 = {15,0};
  19. // event_add(ev2,&five_seconds1);
  20.    event_active(ev1,EV_TIMEOUT,0);
  21.    int tmp = event_base_dispatch(base);
  22.    printf("%d",tmp);
  23.     return 1;
  24. }




 


阅读(1279) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:the greatest common dividor(两个数的最大公约数)

给主人留下些什么吧!~~