2013-12-10 77 views
1

我對這裏很陌生,我希望我做的一切都正確。哪個線程完成多線程?

我想知道如何在等待完成使用WaitForMultipleObjects命令後完成哪個線程完成。目前我有一些沿線:

int checknum; 
int loop = 0; 
const int NumThreads = 3; 

HANDLE threads[NumThreads]; 

WaitForMultipleObjects(NumThreads, threads, false, INFINITE); 
threads[loop] = CreateThread(0, 0, ThreadFunction, &checknum, 0, 0); 

它只能假設有最多三個線程在同一時間運行。所以我有一個循環開始所有三個線程(因此循環值)。問題是,當我再次瀏覽它時,我想將循環的值更改爲任何線程完成其任務的值,以便它可以再次使用。有什麼方法可以找出該陣列中的哪個線程已完成?

我會粘貼我的代碼的其餘部分,但我很確定沒有人需要它的所有147行。我想這個片段就夠了。

回答

2

當第三個參數是false,WaitForMultipleObjects將在任何對象發出信號後立即返回(不需要等待所有對象)。

並且返回值指示哪個對象導致它返回。第一個對象是WAIT_OBJECT_0,第二個對象是WAIT_OBJECT_0 + 1,等等。

+0

我只需要一個線程清理,然後我可以重新使用它。我怎樣才能將WAIT_OBJECT轉換爲0,1或2,這樣我就可以使循環的值等於循環的值,以便循環可以繼續。還是有辦法檢查三個線程中的一個線程是否空閒並且接受第一個線程? – Virlym

+0

你可以說'int index = WaitForMultipleObjects(NumThreads,threads,false,INFINITE) - WAIT_OBJECT_0',但你也應該檢查返回值指示的其他錯誤。 –

+0

非常感謝。我只需要一種方法來找出哪個線程已完成,因此我可以重用它。我在線程開始之前做了錯誤檢查,因爲線程只是一個簡單的數字檢查器。 – Virlym

0

我遠離我的編譯器,我不知道使用windows的onlione IDE,但這裏是您需要的大概想法去做。

const int NumThreads = 3; 
HANDLE threads[NumThreads]; 
//create threads here 
DWORD result = WaitForMultipleObjects(NumThreads, threads, false, INFINITE); 
if(result >= WAIT_OBJECT_0 && result - WAIT_OBJECT_0 < NumThreads){ 
    int index = result - WAIT_OBJECT_0; 
    if(!CloseHandle(Handles[index])){ //need to close to give handle back to system even though the thread has finished 
     DWORD error = GetLastError(); 
     //TODO handle error 
    } 
    threads[index] = CreateThread(0, 0, ThreadFunction, &checknum, 0, 0); 
} 
else { 
    DWORD error = GetLastError(); 
    //TODO handle error 
    break; 
} 

在工作中我們做這個有點不同。我們已經制作了一個包裝所有需要的窗口句柄類型的庫,並執行靜態類型檢查(通過轉換操作符),以確保您不會等待帶有WaitForMultipleObjects(不允許)的IOCompletionPort。等待函數是可變參數,而不是採用一系列的句柄和它的大小,並且專門使用SFINAE在只有一個時使用WaitForSingleObject。它也需要Lambdas作爲參照,並根據信號事件執行相應的一個。

這是什麼樣子:

Win::Event ev; 
Win::Thread th([]{/*...*/ return 0;}); 
//... 

Win::WaitFor(ev,[]{std::cout << "event" << std::endl;}, 
     th,[]{std::cout << "thread" << std::endl;}, 
     std::chrono::milliseconds(100),[]{std::cout << "timeout" << std::endl;}); 

我會極力推薦這種類型的包裝,因爲在編譯器它優化到相同的代碼的一天結束,但你不能讓幾乎同樣多錯誤。

相關問題