我不是一個經驗豐富的C++程序員。所以我只想知道如何實現計時器和timertask,就像java在C++中一樣。我試過timer_create
的例子是在timer_create的man頁面中,但它不按照我的要求工作。 我希望在特定的時間間隔之後事件應該觸發,並且如果特定的條件滿足,那麼計時器應該被取消。像java一樣,C++中是否有類似timer和timertask的東西?
任何幫助將不勝感激。 謝謝, Yuvi。
我不是一個經驗豐富的C++程序員。所以我只想知道如何實現計時器和timertask,就像java在C++中一樣。我試過timer_create
的例子是在timer_create的man頁面中,但它不按照我的要求工作。 我希望在特定的時間間隔之後事件應該觸發,並且如果特定的條件滿足,那麼計時器應該被取消。像java一樣,C++中是否有類似timer和timertask的東西?
任何幫助將不勝感激。 謝謝, Yuvi。
這通常是一個非常困難的問題,因爲您固有地要求一些併發或至少異步處理。
最簡單的單線程解決方案是使用Posix的alarm(2)
之類的東西。這會導致信號在指定時間後發送到您的進程。您需要註冊一個信號處理程序(例如使用signal(2)
),但是您受其所有限制(例如,您只能在處理程序中調用異步安全功能)。
第二個單線程選項是使用select
樣式的(或epoll
樣式)I/O循環並使用內核計時器文件描述符。不過,這是一項非常新的Linux功能,因此可用性會有所不同。
最後,典型的一般解決方案是使用多個線程:爲定時器製作一個專用線程,其唯一目的是在設定的時間間隔內休眠,然後執行一些代碼。爲此,您將必須承擔併發編程責任的全部重量,例如處理共享數據,確保沒有比賽等。
一些更高級別的庫,如Boost.ASIO和新的標準庫提供了一些不錯的功能定時機制,一旦你決定下了多線程的路線。
現在我正在使用類似你的第一個建議'alaram','setitimer'。現在如何使這些函數具有異步安全性? – Yuvi 2012-04-06 11:26:02
@Yuvi:閱讀說明書。有一組異步安全功能。我認爲'abort'和'exec'就是其中之一。但是,在信號處理程序中應該做的主要事情是修改「volatile sigatomic_t」類型的全局變量。 – 2012-04-06 11:28:27
@Yuvi:具體來說,請閱讀'signal(7)'手冊頁以獲取安全Posix函數的完整列表。 – 2012-04-06 12:03:06
我也在尋找像TimerTask這樣的Java,但是當我遇到這個問題時,我需要一個用於Windows C++的東西。在主要研究SO並瞭解通過班級成員職能的一整天之後,我能夠制定一個對我來說很好的解決方案。我意識到我在回答這個問題上遲了多年,但也許有人仍然在尋找這個解決方案會覺得這很有用。
這是一個僅在Windows 10上使用Visual Studio C++測試的Windows解決方案。我仍然在學習C++,所以如果我違反了任何規則,請保持溫柔。我意識到例外是基本的,但它們很容易根據您的需求進行定製。我創建了一個類似於Java類的TimerTask類。您需要從TimerTask類派生一個新的用戶類,並創建一個「任務」函數,其中包含您要定期執行的代碼。這裏是TimerTask類:
--TimerTask.h--
#pragma once
#include <thread>
class TimerTask {
HANDLE timeoutEvent;
DWORD msTimeout;
bool exit = false;
void* pObj;
static void taskWrapper(TimerTask* pObj) {
while (!pObj->exit) {
DWORD waitResult = WaitForSingleObject(pObj->timeoutEvent, pObj->msTimeout);
if (pObj->exit)
break;
pObj->task();
}
}
public:
TimerTask::TimerTask() {
timeoutEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!timeoutEvent) {
throw "TimerTask CreateEvent Error: ";
}
}
TimerTask::~TimerTask() {
CloseHandle(timeoutEvent);
}
// Derived class must create task function that runs at every timer interval.
virtual void task() = 0;
void start(void* pObj, DWORD msTimeout) {
this->pObj = pObj;
this->msTimeout = msTimeout;
std::thread timerThread(taskWrapper, (TimerTask*)pObj);
timerThread.detach();
}
void stop() {
exit = true;
if (!SetEvent(timeoutEvent))
throw "TimerTask:stop(): Error: ";
}
};
這裏是一個使用示例。爲了簡潔起見,我沒有包含錯誤檢查。
--Test.cpp--
#include "Windows.h"
#include <iostream>
#include "TimerTask.h"
using namespace std;
class KeepAliveTask : public TimerTask {
public:
void task() {
cout << "Insert your code here!\n";
}
};
int main()
{
cout << "Hello, TimerTask!\n";
KeepAliveTask keepAlive;
keepAlive.start(&keepAlive, 1000); // Execute once per second
Sleep(5100); // Pause 5.1s to give time for task thread to run.
keepAlive.stop();
Sleep(1000); // Pause another sec to give time for thread to stop.
return 0;
}
我不能說C++ 11,但在(標準)C++詞庫的其餘部分,沒有。不過,Qt和Boost有一些很好的併發工具。 – jpm 2012-04-06 10:49:20