Libevent学习——定时器基本运用

3.1、首先初始化libevent库,并保存返回的指针
 
   
  1. struct event_base *base = event_base_new();
这一步相当于初始化一个Reactor实例;在初始化libevent后,就可以注册事件了。
3.2、定义两个结构体,分别代表事件和定时器值
 
   
  1. struct event timeout;//定时器事件
  2. struct timeval tv;//定时器值

3.3、将事件和event_base绑定
 
   
  1. event_assign(&timeout, base, -1, flags, timeout_cb, (void*)&timeout);
flags参数代表了事件标志。
 
    
  1. #define EV_TIMEOUT 0x01//这个标志表示某超时时间流逝后事件成为激活的。构造事件的时候,EV_TIMEOUT标志是被忽略的:可以在添加事件的时候设置超时,也可以不设置。超时发生时,回调函数的what参数将带有这个标志。
  2. #define EV_READ 0x02//表示指定的文件描述符已经就绪,可以读取的时候,事件将成为激活的。
  3. #define EV_WRITE 0x04//表示指定的文件描述符已经就绪,可以写入的时候,事件将成为激活的。
  4. #define EV_SIGNAL 0x08//用于实现信号检测
  5. #define EV_PERSIST 0x10//表示事件是“持久的”
  6. #define EV_ET 0x20//表示如果底层的event_base后端支持边沿触发事件,则事件应该是边沿触发的。这个标志影响EV_READ和EV_WRITE的语义。


我们可以去看下event_assign函数:
 
  
  1. int event_assign(struct event *, struct event_base *, evutil_socket_t, short,event_callback_fn, void *);
来看下各个参数:  
  @param ev an event struct to be modified//事件的结构体,也就是定时器事件timeout
  @param base the event base to which ev should be attached.//需要绑定的event_base
  @param fd the file descriptor to be monitored//需要监视文件描述符,当fd=-1时,事件被手动激活或者定时器溢出激活
  @param events desired events to monitor; can be EV_READ and/or EV_WRITE//事件的模式
  @param callback callback function to be invoked when the event occurs//回调函数, ,当fd上的事件event发生时,调用该函数执行处理,它有三个参数,调用时由event_base负责传入,按顺序,实际上就是event_assign 的fd, event和arg; arg:传递给cb函数指针的参数
  @param callback_arg an argument to be passed to the callback function//传给回调函数的参数
3.4、在创建定时器事件时,使用的是struct event timeout,也可以用event_new函数动态分配,这样就不需要 event_assign函数了。
 
   
  1. struct event *timeout;
  2. timeout= evsignal_new(base, -1, flags, timeout_cb, (void*)&timeout);
在分配后可以用event_free来释放

3.5、添加事件
 
   
  1. event_add(&timeout, &tv);
3.6、 程序进入无限循环,等待就绪事件并执行事件处理
 
  
  1. event_base_dispatch(base);

3.7、为使用方便,libevent提供了一些以evtimer_开头的宏,用于替代event_*调用来操作纯超时事件。使用这些宏能改进代码的清晰性。
 
   
  1. #define evtimer_assign(ev, b, cb, arg) \
  2. event_assign((ev), (b), -1, 0, (cb), (arg))
  3. #define evtimer_new(b, cb, arg) event_new((b), -1, 0, (cb), (arg))
  4. #define evtimer_add(ev, tv) event_add((ev), (tv))
  5. #define evtimer_del(ev) event_del(ev)
  6. #define evtimer_pending(ev, tv) event_pending((ev), EV_TIMEOUT, (tv))
  7. #define evtimer_initialized(ev) event_initialized(ev)
3.8、程序代码
 
   
  1. #include "stdafx.h"
  2. #include <winsock2.h>
  3. #include <event2/event-config.h>
  4. #include <event2/event.h>
  5. #include <event2/event_struct.h>
  6. #include <event2/util.h>
  7. static void timeout_cb(evutil_socket_t fd, short event, void *arg)
  8. {
  9. struct event *timeout;
  10. timeout = (struct event *)arg;
  11. struct timeval tv;
  12. evutil_timerclear(&tv);
  13. tv.tv_sec = 2;
  14. event_add(timeout, &tv);
  15. printf("timeout\n");
  16. }
  17. int _tmain(int argc, _TCHAR* argv[])
  18. {
  19. WSADATA wsa_data;
  20. WSAStartup(0x0201, &wsa_data);
  21. struct event_base *base = event_base_new();
  22. struct event timeout;//定时器事件
  23. struct timeval tv;//定时器值
  24. int flags = EV_TIMEOUT;
  25. event_assign(&timeout, base, -1, flags, timeout_cb, (void*)&timeout);
  26. evutil_timerclear(&tv);
  27. tv.tv_sec = 2;
  28. tv.tv_usec = 0;
  29. event_add(&timeout, &tv);
  30. event_base_dispatch(base);
  31. return 0;
  32. }

猜你喜欢

转载自blog.csdn.net/u010977122/article/details/78036098