2011-07-18 147 views
2

我有一個不同的線程,使一些東西的項目。C++使用一個線程定時器

這一切都不錯,但我想呼籲各20ms的一些功能(例如),但考慮花功能的時候......我試圖解釋更好......我調用該函數,函數花6ms的退出,所以我希望線程睡眠14毫秒(20 - 6),在下次被調用時,函數花了12毫秒,所以睡眠將只有8ms的.... 我該怎麼辦呢? 這裏是我的代碼:

// thread constructor 
DWORD dwThreadId, dwThrdParam = 1; 
HANDLE thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)workerFunc, &dwThrdParam, 0, &dwThreadId); 

// thread function 
DWORD WINAPI workerFunc(LPDWORD lpdwParam) 
{ 
    while(true) 
    { 
     myFunction(); 
     Sleep(???); 
    } 
    return 0; 
} 

謝謝!

+0

我想進入獲取系統時間之前,也返回獲取系統時間後發揮作用,減去他們接着睡20 - 結果。這將是一個近似值,因爲你會失去計算你應該等待多少的時間。 –

回答

2

這個什麼:

clock_t start, end; 
while(true) 
{ 
    start = clock(); 
    myFunction(); 
    end = clock(); 
    Sleep(20-(end-start)*CLOCKS_PER_SEC/1000.0); 
} 
+0

+1,但如果end-start> 20,則可能需要防範後衛,因爲Sleep需要一個unsigned int(http://preview.tinyurl.com/5uydxea) – sum1stolemyname

1

使用GetTickCount在致電myFunc之前和致電myFunc之後。差異給你在myFunc花費的時間。請注意,這次包含了由於操作系統調度而導致的進程花費的時間。

2

一個簡單的方法是發送線程睡眠時間的變化量:

void periodic_function() 
{ 
    /* function body */ 

    timestamp = get_time(); // pseudo-function 
    remaining_sleep_time = std::min(0, 20 - (timestamp - last_timestamp)); 
    last_timestamp = timestamp; 
    milli_sleep_callback(remaining_sleep_time, periodic_function); 
} 

你需要一個合適穩定的時鐘功能get_time()和睡眠功能 - 嘗試<chrono><tr1/chrono>頭。在這個例子中,我假設你有一個計時器回調(就像在boost.ASIO中),但你也可以做一個無限循環或類似的東西。

如果函數體永遠不會超過20ms,這個函數就可以工作,不過如果你的函數需要更長的話,它可以快速追趕。如果你想同步到一個全球20ms節奏,你必須添加另一個全局步數計數器或類似的東西。

0

如果你需要的精度,使用NtSetTimerResolution當程序啓動到設定的定時分辨率。是的,這是無證的功能,但效果很好。您也可以使用NtQueryTimerResolution知道定時分辨率(之前設置和設置新的決議,以確保之後)。

您需要動態獲取這些函數的地址,使用GetProcAddressNTDLL.DLL,因爲它沒有在頭文件或任何LIB文件中聲明。

設置定時器分辨率這樣會影響Sleep時,Windows定時器,返回當前時間等