定时器类在Linux中

我需要一个计时器来执行分辨率相对较低的callback。 在Linux中实现这样的C ++定时器类的最好方法是什么? 有没有我可以使用的图书馆?

Solutions Collecting From Web of "定时器类在Linux中"

如果你正在写一个框架(Glib,Qt,Wx,…),你将已经有一个具有定时回调函数的事件循环。 我会认为情况并非如此。

如果您正在编写自己的事件循环,则可以为自己的事件调度程序使用gettimeofday / select对( struct timeval ,微秒精度)或clock_gettime / nanosleep对( struct timespec ,纳秒精度)。 即使后者的界面更高分辨率,调度从来没有那么准确,所以采取任何最适合的。

 #include <algorithm> #include <functional> #include <vector> #include <errno.h> #include <sys/time.h> #include <unistd.h> 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, const struct event &, const struct event &> { bool operator()(const struct event &a, const struct event &b) { return !tv_le(a.when, b.when); } } cmp; vector<struct event> 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

尝试time.h中定义的clock_gettime()函数:

 int clock_gettime(clockid_t clk_id, struct timespec *tp); struct timespec { time_t tv_sec; /* seconds */ long tv_nsec; /* nanoseconds */ }; 

通常你可以这样称呼它:

 struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); 

time.h头文件中的timeval结构就是你正在寻找的东西。 它有时间在几秒和几纳秒。 所以总时间(以纳秒为单位)是timeval.tv_sec * 1000000 + timeval.tv_usec。 我觉得很简单。

 #include <time.h> timeval theStartTime; gettimeofday(&theStartTime); std::cout<<"The time we got's seconds field = "<<theStartTime.tv_sec<<std::endl; std::cout<<"The time we got's nanoseconds field = "<<theStartTime.tv_usec<<std::endl; 

这里是定时器类的链接。 你只需要创建计时器并将其值传递给自动重装或不重装。 一个指向回调函数的指针。 或者如果你想要它通过线程或信号来处理。 如果你选择信号,那么你也必须通过signo。

http://timerlinux.codeplex.com/

如果你想学习更多关于定时器或者信号的知识,那么有一本好书叫做linux系统编程。 你只需要阅读3章并解释它。