我需要一个计时器来执行分辨率相对较低的回调.在Linux中实现这样的C++计时器类的最佳方法是什么?我可以使用任何库吗?
如果你是在一个框架内写的(Glib,Qt,Wx,...),你已经有了一个带有定时回调功能的事件循环.我会假设情况并非如此.
如果您正在编写自己的事件循环,则可以为自己的事件调度程序使用gettimeofday
/ select
pair(struct timeval
,微秒精度)或clock_gettime
/ nanosleep
pair(struct timespec
,纳秒精度).即使后一种界面具有更高的分辨率,但无论如何调度都不是那么准确,所以最好采取任何最佳方案.
#include#include #include #include #include #include using namespace std; class scheduler { public: scheduler(); int events(); void addEvent(const struct timeval, int (*)(void *), void *); int dispatchUntil(const struct timeval &); bool waitUntil(const struct timeval * = NULL); int loopUntil(const struct timeval * = NULL); private: static bool tv_le(const struct timeval &, const struct timeval &); struct event { struct timeval when; int (*callback)(void *); void *data; }; static struct _cmp : public binary_function { bool operator()(const struct event &a, const struct event &b) { return !tv_le(a.when, b.when); } } cmp; vector heap; }; bool scheduler::tv_le(const struct timeval &a, const struct timeval &b) { return a.tv_sec < b.tv_sec || a.tv_sec == b.tv_sec && a.tv_usec <= b.tv_usec; } scheduler::scheduler() : heap() {} int scheduler::events() { return heap.size(); } void scheduler::addEvent(const struct timeval when, int (*callback)(void *), void *data) { struct event ev = {when, callback, data}; heap.push_back(ev); push_heap(heap.begin(), heap.end(), cmp); } int scheduler::dispatchUntil(const struct timeval &tv) { int count = 0; while (heap.size() > 0 && tv_le(heap.front().when, tv)) { struct event ev = heap.front(); pop_heap(heap.begin(), heap.end(), cmp); heap.pop_back(); ev.callback(ev.data); count++; } return count; } bool scheduler::waitUntil(const struct timeval *tv) { if (heap.size() > 0 && (!tv || tv_le(heap.front().when, *tv))) tv = &heap.front().when; if (!tv) return false; struct timeval tv2; do { gettimeofday(&tv2, NULL); if (tv_le(*tv, tv2)) break; tv2.tv_sec -= tv->tv_sec; if ((tv2.tv_usec -= tv->tv_usec) < 0) { tv2.tv_sec--; tv2.tv_usec += 1000000; } } while (select(0, NULL, NULL, NULL, &tv2) < 0 && errno == EINTR); return heap.size() > 0 && tv_le(*tv, heap.front().when); } int scheduler::loopUntil(const struct timeval *tv) { int counter = 0; while (waitUntil(tv)) counter += dispatchUntil(heap.front().when); return counter; }
警告:我喜欢C.我从不写C++.我只是假装懂语言.
免责声明:刚刚编写,完全未经测试.基本思想是将事件保存在优先级队列中,等到第一个队列,运行它,然后重复.
使用boost :: asio库.它有同步和异步定时器,可以调用回调.
http://www.boost.org/doc/libs/1_37_0/doc/html/boost_asio/tutorial.html