我需要一個定時器來執行分辨率相對較低的回調。在Linux中實現這種C++定時器類的最佳方式是什麼?有我可以使用的任何圖書館嗎?linux中的計時器類
2
A
回答
14
如果你的框架(油腔滑調,Qt的,蠟質,...)內以書面形式,你已經有一個事件循環與定時回調功能。我會認爲情況並非如此。
如果你正在寫自己的事件循環,可以使用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++。我只是假裝知道這門語言。
免責聲明:剛剛寫完,完全沒有經過測試。基本思想是將事件保存在優先隊列中,等到第一個隊列,運行並重復。
0
嘗試clock_gettime()函數,在time.h中定義:
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);
7
使用Boost :: ASIO庫。它具有同步和異步定時器,可以調用回調。
http://www.boost.org/doc/libs/1_37_0/doc/html/boost_asio/tutorial.html
0
從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;
0
這裏是定時器類的鏈接。你只需要創建計時器並將其傳遞給自動重裝或不重裝。一個指向回調函數的指針。或者如果你想要它由線程或信號處理。如果你選擇信號,那麼你也必須通過signo。
http://timerlinux.codeplex.com/
如果妳想要學習更多關於定時器或信號有一個很好的書叫做linux系統編程。你只需要閱讀3章並解釋它。
相關問題
- 1. Linux的可編程間隔計時器
- 2. Linux是計時器的過程
- 3. 準確的計時器類
- 4. 類似的JavaScript計時器
- 5. Linux的睡眠定時器+刪除計時器+上喚醒
- 6. 在ASP.NET中的計時器類
- 7. Linux內核2.6中的計時
- 8. 在Java中創建計時器類
- 9. 在Linux中使用C++實現低開銷間隔計時器
- 10. 在Linux中使用C++創建計時器隊列
- 11. 計時器監聽器類號錯誤
- 12. 實現類似於Stackoverflow的計時器
- 13. Linux中的看門狗定時器
- 14. Python中的計時器
- 15. 服務中的計時器
- 16. javascript中的計時器
- 17. Android中的計時器
- 18. ASP.NET中的計時器AJAX
- 19. Android中的計時器
- 20. clojure中的計時器?
- 21. Python中的計時器
- 22. Android中的計時器JNI
- 23. 根據vb.net中的計時器計時器顯示消息
- 24. 計時器 - 計算時間
- 25. 倒計時計時器
- 26. 刪除線程計時器類?
- 27. 在計時器上更改類Jquery
- 28. 計時器類...沒有更新
- 29. 難以理解ActionScript 3計時器類
- 30. Swift 3計時器在計時器
什麼是相對較低的分辨率? – Loki 2009-02-02 18:12:02
哈哈,洛基。正是我想當我讀他的問題 – 2009-02-03 03:53:08
數百毫秒到秒 – jackhab 2009-02-03 08:11:25