2012-04-06 109 views
0

我不是一個經驗豐富的C++程序員。所以我只想知道如何實現計時器和timertask,就像java在C++中一樣。我試過timer_create的例子是在timer_create的man頁面中,但它不按照我的要求工作。 我希望在特定的時間間隔之後事件應該觸發,並且如果特定的條件滿足,那麼計時器應該被取消。像java一樣,C++中是否有類似timer和timertask的東西?

任何幫助將不勝感激。 謝謝, Yuvi。

+0

我不能說C++ 11,但在(標準)C++詞庫的其餘部分,沒有。不過,Qt和Boost有一些很好的併發工具。 – jpm 2012-04-06 10:49:20

回答

1

這通常是一個非常困難的問題,因爲您固有地要求一些併發或至少異步處理。

最簡單的單線程解決方案是使用Posix的alarm(2)之類的東西。這會導致信號在指定時間後發送到您的進程。您需要註冊一個信號處理程序(例如使用signal(2)),但是您受其所有限制(例如,您只能在處理程序中調用異步安全功能)。

第二個單線程選項是使用select樣式的(或epoll樣式)I/O循環並使用內核計時器文件描述符。不過,這是一項非常新的Linux功能,因此可用性會有所不同。

最後,典型的一般解決方案是使用多個線程:爲定時器製作一個專用線程,其唯一目的是在設定的時間間隔內休眠,然後執行一些代碼。爲此,您將必須承擔併發編程責任的全部重量,例如處理共享數據,確保沒有比賽等。

一些更高級別的庫,如Boost.ASIO和新的標準庫提供了一些不錯的功能定時機制,一旦你決定下了多線程的路線。

+0

現在我正在使用類似你的第一個建議'alaram','setitimer'。現在如何使這些函數具有異步安全性? – Yuvi 2012-04-06 11:26:02

+0

@Yuvi:閱讀說明書。有一組異步安全功能。我認爲'abort'和'exec'就是其中之一。但是,在信號處理程序中應該做的主要事情是修改「volatile sigatomic_t」類型的全局變量。 – 2012-04-06 11:28:27

+0

@Yuvi:具體來說,請閱讀'signal(7)'手冊頁以獲取安全Posix函數的完整列表。 – 2012-04-06 12:03:06

0

我也在尋找像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; 
} 
相關問題