2013-09-30 46 views
2

我正在使用C++ 11上的線程庫來做一些事情。問題是我的線程數量有限(4)。幾個線程的多個任務

我會知道如何對付它:

#include <iostream> 
#include <string> 
#include <vector> 
#include <thread> 

#define NUMBER_OF_THREADS 4 

void foo(const std::string& astring) 
{ 
    std::cout << astring << std::endl; 
} 

int main() 
{ 
    std::vector<std::string> list_of_strings(100); 
    // values assigned 
    std::vector<std::thread> list_of_threads(NUMBER_OF_THREADS); 
    for(std::vector<std::string>::const_iterator it_string = list_of_strings.begin() ; it_string != list_of_strings.end() ; ++it_string) 
    { 
     bool check = false; 
     unsigned int = 0; 
     while(!check) // loop which assigns the next task to the first thread ready. 
     { 
      if(check = list_of_threads.at(i).ISFREE()) // how to do ? 
      { 
       list_of_threads.at(i) = thread(&foo,*it_string); 
      } 
      else 
      { 
       i = (i + 1) % NUMBER_OF_THREADS; 
      } 
     } 
    } 
    for(std::vector<std::thread>::iterator it = list_of_threads.begin() ; it != list_of_threads.end() ; ++it) 
     it->join(); // the main thread is waiting for all threads before closing. 
    return 0; 
} 

但我不知道如何檢查,如果線程準備一個新的任務或沒有。任何想法 ?

+1

德魯霍爾迄今爲止已是最好的答案。忘記使用一些令人討厭的(並且很可能是bug),「線程管理器循環」來顯式管理線程,並將任務排隊到池中。 –

+0

@BradTilley:是的,我在我的代碼中使用它,我只是在我的問題中編寫了#define,因爲它更明顯:p – Alfred

回答

5

通常的解決方案是將任務存儲在共享隊列中(由互斥鎖和條件變量保護),並讓每個線程在完成當前任務時檢查其他任務。這樣,每個線程都保持忙碌,程序的其餘部分可以保持對配置的無知。

+0

謝謝^^將任務存儲到共享隊列似乎是個好主意,但我該怎麼做?有線程管理器的例子嗎? – Alfred

3

沒有好的內置方式。你可以使用std::async而不是std::thread,它返回一個std::future,你可以查詢 - 這在一般情況下可能更可取,因爲它完全是你在做的 - 處理工作項目時不需要花費整個操作系統線程的開銷。

或者你可以讓你的線程發信號通知它已完成(比如說通過std::atomic或更可能是std::condition_variable),然後從主線程中獲取.join()以確保其真正終止。

+0

'async'很可怕,可能會被棄用於C++ 14。 –

+0

@ R.MartinhoFernandes出於好奇,爲什麼'異步'是可怕的? – Sungmin

+0

@Sungmin這是'async'最明顯的問題http://chat.stackoverflow.com/transcript/message/8951379#8951379。 –

0

我對std :: thread不熟悉,但假設沒有更好的線程類可用,它具有您需要的功能(請參閱Mikes的答案也許),我會建議您編寫基於std ::線。 std :: thread會得到一個指向你自己成員函數的函數指針,它設置一個線程正忙的內部標誌,然後調用外部提供的函數,然後重置所述標誌。添加一個返回標誌狀態的方法IsBusy(),就完成了。

+0

IsBusy()會提供有意義的信息嗎?我可以看到它提供了誤報(線程在你提問後很快就會停止)*和*漏報(線程即將開始工作,並且只會在你提出問題後立即設置標誌)。 (這甚至假設該標誌是一個原子變量) –

+0

@ R.MartinhoFernandes - 是的,這些'線程管理器'循環與狀態檢查顯然是越野車,非明顯的越野車或,(很少),只是絕望貧窮性能:(( –

+0

)當然,這絕不是一個準備好使用的解決方案,人們將不得不花費相當多的時間來正確地實施和測試這樣的課程。其他答案可能更適合Op描述。 – SvenS