Libevent 編程- 定時器事件(timer event)
本文介紹Libevent 三種事件之一的定時器事件。 該事件可以用來註冊定時事件和週期性事件。Libevent 根據所有定時器事件的最小超時時間來設置系統 I/O 的 timeout 值,當系統I/O 返回時,再激活就緒的定時器事件,如此 Timer 事件便可融合在系統 I/O 機制中。
定時器事件的實現基於一種經典的數據結構-小根堆,相關的數據結構定義和操作在minheap-internal.h中。其處理與其他兩種事件類似。 不同之處在於定時器事件不依賴於文件描述符,在初始化該類型事件時,文件描述符處的參數爲-1,在註冊定時器事件是,後面的時間參數不爲 NULL。如下:
event_assign(&ev_time, base, -1, flags, timeout_cb, (void*)&ev_time); //初始化定時器事件ev_time,準備註冊到base
event_add(&ev_time, &tv);//註冊定時器事件
下面是 Libevent 的自身測試代碼 :
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <event2/event.h>
#include <event2/event_struct.h>
#include <event2/util.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct timeval lasttime;
static int event_is_persistent;
static void timeout_cb(evutil_socket_t fd, short events, void *arg) {
struct timeval newtime, difference;
evutil_gettimeofday(&newtime, NULL);
evutil_timersub(&newtime, &lasttime, &difference);
double elapsed = difference.tv_sec + (difference.tv_usec / 1.0e6);
printf("timeout_cb called at %d: %.3f seconds elapsed.\n",
(int)newtime.tv_sec, elapsed);
lasttime = newtime;
if(event_is_persistent) {
struct event* ev_time = arg;
struct timeval tv;
evutil_timerclear(&tv);
tv.tv_sec = 2;
event_add(ev_time, &tv);
}
}
int main(int argc, char *argv[])
{
int flags;
if(2 == argc && !strcmp(argv[1], "-p")) {
event_is_persistent = 1;
flags = EV_PERSIST;
} else if(1 == argc) {
event_is_persistent = 0;
flags = 0;
} else {
printf("Usage: %s [-p]\n", argv[0]);
exit(EXIT_FAILURE);
}
struct event ev_time;
struct event_base *base = event_base_new();
event_assign(&ev_time, base, -1, flags, timeout_cb, (void*)&ev_time);
struct timeval tv;
evutil_timerclear(&tv);
tv.tv_sec = 2;
event_add(&ev_time, &tv);
evutil_gettimeofday(&lasttime, NULL);
event_base_dispatch(base);
event_base_free(base);
exit(EXIT_SUCCESS);
}
我對測試代碼作了些小改動,全局變量event_is_persistent是標誌週期事件的開關,程序提供前面提到的兩種 timer 事件,關於註冊週期性事件我查看了 Libevent 的一些資料發現所謂週期事件就是重複註冊 timer 事件,剛開始接觸 timer 事件時,我一直以爲 event_add函數的第二個時間參數表示週期,等自己嘗試過後才發現那個值表示 timeout。以下是程序編譯運行結果:
允許轉載