
libevent定时器是怎么实现的
发布日期:2021-05-08 05:59:08
浏览次数:21
分类:精选文章
本文共 3218 字,大约阅读时间需要 10 分钟。
1. 定时器是怎么实现的
在之前的文章里我们讲过,libevent最后处理都是在event_base_loop调用了相应的dispatch函数,定时器也是在dispatch函数中处理的。
还是以epoll为例,在epoll_dispatch函数有以下一段代码:
if (tv != NULL) { timeout = evutil_tv_to_msec_(tv); if (timeout < 0 || timeout > MAX_EPOLL_TIMEOUT_MSEC) { /* Linux kernels can wait forever if the timeout is * too big; see comment on MAX_EPOLL_TIMEOUT_MSEC. */ timeout = MAX_EPOLL_TIMEOUT_MSEC; } } epoll_apply_changes(base); event_changelist_remove_all_(&base->changelist, base); EVBASE_RELEASE_LOCK(base, th_base_lock); //epoll_wait的最后一个参数即为超时时间 res = epoll_wait(epollop->epfd, events, epollop->nevents, timeout); EVBASE_ACQUIRE_LOCK(base, th_base_lock); if (res == -1) { if (errno != EINTR) { event_warn("epoll_wait"); return (-1); } return (0); }
从上面代码可以看出,是通过epoll_wait的超时机制来实现定时器的,这样我们就可以知道,其实定时器就是利用了select和epoll_wait等这些系统函数的超时机制,才实现的定时器。
总的来讲,定时器就是在事件主循环中,等待网络调用超时,当超时以后,将任务写入队列,然后处理队列,调用回调函数,这样就实现了定时器。
2. 定时器代码实现
看libevent源代码中例子:
#include#include #include #include #ifdef EVENT__HAVE_SYS_TIME_H#include #endif#include #include #include #include #include #include #include #include struct timeval lasttime;int event_is_persistent;static voidtimeout_cb(evutil_socket_t fd, short event, void *arg){ struct timeval newtime, difference; struct event *timeout = (struct event*)arg; double elapsed; evutil_gettimeofday(&newtime, NULL); evutil_timersub(&newtime, &lasttime, &difference); 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 timeval tv; evutil_timerclear(&tv); tv.tv_sec = 2; event_add(timeout, &tv); }}intmain(int argc, char **argv){ struct event timeout; struct timeval tv; struct event_base *base; int flags; if (argc == 2 && !strcmp(argv[1], "-p")) { event_is_persistent = 1; flags = EV_PERSIST; } else { event_is_persistent = 0; flags = 0; } /* Initalize the event library */ base = event_base_new(); /* Initalize one event */ event_assign(&timeout, base, -1, flags, timeout_cb, (void*) &timeout); evutil_timerclear(&tv); tv.tv_sec = 3; event_add(&timeout, &tv); evutil_gettimeofday(&lasttime, NULL); event_base_dispatch(base); return (0);}
实现三秒调用一次回调函数,执行结果如下:
timeout_cb called at 1535528104: 3.001 seconds elapsed.timeout_cb called at 1535528107: 3.000 seconds elapsed.timeout_cb called at 1535528110: 3.001 seconds elapsed.timeout_cb called at 1535528113: 2.999 seconds elapsed.timeout_cb called at 1535528116: 3.000 seconds elapsed.timeout_cb called at 1535528119: 3.002 seconds elapsed.timeout_cb called at 1535528122: 2.999 seconds elapsed.timeout_cb called at 1535528125: 3.001 seconds elapsed.timeout_cb called at 1535528128: 3.000 seconds elapsed.timeout_cb called at 1535528131: 3.000 seconds elapsed.timeout_cb called at 1535528134: 2.999 seconds elapsed.timeout_cb called at 1535528137: 3.000 seconds elapsed.timeout_cb called at 1535528140: 3.000 seconds elapsed.timeout_cb called at 1535528143: 3.000 seconds elapsed.timeout_cb called at 1535528146: 3.000 seconds elapsed.timeout_cb called at 1535528149: 3.002 seconds elapsed.
发表评论
最新留言
第一次来,支持一个
[***.219.124.196]2025年04月03日 16时41分16秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
java大数据最全课程学习笔记(2)--Hadoop完全分布式运行模式
2021-05-09
大部分程序员还不知道的 Servelt3 异步请求,原来这么简单?
2021-05-09
[apue] popen/pclose 疑点解惑
2021-05-09
[apue] getopt 可能重排参数
2021-05-09
移动互联网恶意软件命名及分类
2021-05-09
adb shell am 的用法
2021-05-09
PySide图形界面开发(一)
2021-05-09
Android如果有一个任意写入的漏洞,如何将写权限转成执行权限
2021-05-09
三角网格体积计算
2021-05-09
现代3D图形编程学习-基础简介(2) (译)
2021-05-09
Github教程(3)
2021-05-09
vue实现简单的点击切换颜色
2021-05-09
vue3 template refs dom的引用、组件的引用、获取子组件的值
2021-05-09
深入浅出mybatis
2021-05-09
Zookeeper快速开始
2021-05-09
882. Reachable Nodes In Subdivided Graph
2021-05-09
402. Remove K Digits
2021-05-09
375. Guess Number Higher or Lower II
2021-05-09
650. 2 Keys Keyboard
2021-05-09
764. Largest Plus Sign
2021-05-09