2016-03-05 187 views
2

我知道定時器是由執行的週期性動作,但我不知道,如果計時器是在一個線程來執行定期操作的最佳方式,我想要做的是正從工作線程的一些信息,要更清楚:有一個主線程需要獲得另一個線程(woker)的屬性,這個線程是變體,這就是爲什麼我需要在每個時間間隔內獲得它的值。 它是這樣的:如何在線程中每秒執行一個動作?

procedure mainThread.execute; 
begin 
// every second : 
val := workerThread.property; 
end; 

正常情況下,主線程需要等待一秒鐘,然後獲得的價值,例如:

procedure mainThread.execute; 
begin 
while (condition) do 
begin 
sleep(1000); 
val := workerThread.property; 
end; 

但是,如果一個工人線程終止,並且主線程仍然等待得到值sleep(1000),這將導致時間的損失,因爲當工作線程終止時,主線程應立即退出循環。我不希望主線程等待,如果工作線程已經終止它的工作(如果工作線程少於1秒,就不需要獲得該屬性值),這就是爲什麼我不應該這樣做。 我也想過用waitformultipleobjects withing這個循環,那麼假設我有許多工人:,它寧願:

procedure mainThread.execute; 
begin 
while (condition) do 
begin 
waitForMultipleObjects(Threads, @Array, True, 1000); 
//If elapsed Time < 1000 , this means that all threads terminated, then main thread must quit this loop 
//If elapsed Time = 1000 : 
val := workerThread.property; 
// Calculate the new value of condition 
end; 

所以,我想實現的是:主線程必須退出循環只有當:

  • 所有工作線程終止(後立即終止),而主線程正在等待獲得屬性值,如果線程終止,主線程退出循環,如果沒有,就繼續等待,直到經過時間= 1秒,並獲得新的價值。
  • 條件爲假。 我將條件設置爲false沒有問題,因爲我必須計算每次迭代的結果並確定其新值。

我希望我在我解釋清楚。

感謝您的回覆。

+1

最簡單的方法是在循環中調用「Sleep(1000)」,在每次循環迭代中執行您的操作。或者,使用'CreateWaitableTimer()'和'WaitForSingleObject()'而不是'Sleep()'。 –

+0

你爲什麼認爲計時器不是最好的方法? –

+0

抱歉不清楚,請參閱我的編輯。 – Safa

回答

4

WaitForMultipleObjects的確,你應該調用的函數。你的問題雖然是你沒有檢查返回值。無論何時調用Windows API函數,都有一條經驗法則:

總是檢查函數返回的值。

你會避免很多問題,如果你遵循的規則。

在這種情況下documentation說,傳遞TruebWaitAll時:

  • WAIT_OBJECT_0甲返回值(WAIT_OBJECT_0 + nCount- 1)意味着該函數返回,因爲所有指定的對象被髮信號。
  • WAIT_TIMEOUT的返回值表示函數返回,因爲指定的超時時間過去。
  • 返回值WAIT_FAILED表示由於某種原因調用失敗,並且您應該致電GetLastError以查明原因是什麼。

請注意,您不必擔心WAIT_ABANDONED_0到(WAIT_ABANDONED_0 + nCount- 1)的情況下,因爲你沒有傳遞任何互斥對象。

相關問題