2016-09-20 18 views
0

鑑於這種for循環:C++運行併發for循環,甚至可能嗎?

std::vector<std::string> V={"element1","element2","element3"}; 

for(int i=V.size(); i--;) 
{ 
std::cout<<i<<std::endl; 
} 

是否有可能運行的每個循環的循環並行?所以每個std :: cout立刻出現?

我有一個向量的函數指針,我需要循環並執行所有在同一時間,一個接一個。

注意:在這種情況下,std :: thread,std :: async沒有幫助完整,因爲我不知道向量的大小,因此必須在每個循環中創建一個線程並運行它。這不會導致併發性。

+0

你也可以在這裏查看:http://en.cppreference.com/w/cpp/experimental/parallelism – Hayt

+1

你應該進一步闡明你希望你的輸出到std :: cout的樣子。你需要輸出的特定順序嗎? – midor

+1

總之不可能,即使你使用線程他們,都不會在同一時間執行 –

回答

0

如果可執行文件指的是您想要啓動的獨立應用程序,那麼您不需要使用線程。您只需在一個線程中逐個啓動可執行文件,而無需等待完成。你可以把它們的PID放入一個向量中。然後在分開的循環中等待,直到這些過程完成,再一個一個。

但是,如果這是你在程序中需要做的唯一事情,那麼你最好考慮用bash寫它。

+0

這裏我的意思是函數指針... –

+0

然後std :: thread是你的朋友。將要執行的每個函數都包裝到一個std ::線程中,並將它們放入一個向量中,然後等待它們。 –

0

您可以並行運行這些可執行文件。這與並行運行for循環沒有任何關係。這是您的操作系統的更多功能。

對於Linux查看如何使用fork()/exec()/system()運行進程。

對於Windows查找如何使用CreatrProcess()運行進程。

0

是否可以同時運行for循環的每個循環?

是的。 C++標準庫提供了實現併發性的低級工具。只需在每次迭代中啓動一個新線程 - 並且在所有線程都啓動之前不加入。

注:標準::線程的std ::異步不利於全在這種情況下,我不知道向量的大小,併爲此必須創建一個線程每個循環並運行它..這不會導致併發性。

你錯了。 std::thread(以及可能的std::asnyc)也很有用,可用於在這種情況下實現併發。在每個循環中創建線程並不妨礙併發。一個平凡的演示使用函數指針,因爲這是你真正打算使用:

std::vector<void(*)()> function_pointers = get_the_stuff(); 
for(auto f : function_pointers) { 
    std::thread t(f); 
    t.detach(); 
} 

另外,稍微更復雜的,方法是創建線程的向量。這可以讓你等到所有人都通過加入來執行。

-

std::thread和朋友併發低級別的工具和它可能是值得在他們創造一個抽象 - 或使用由第三方提供的現有抽象。

此外,我敦促你重新考慮。你說你不知道矢量的大小。當然,你的硬件提供者也不知道這個向量。他們如何知道爲您提供足夠的cpu內核來並行執行所有線程?更好的方法是根據可用內核的數量使用恆定的線程池,以避免額外線程的開銷。

1

它是OpenMP的一個工作:

#pragma omp parallel for 
for(int i = 0; i < V.size(); ++i) 
{ 
    std::cout<<i<<std::endl; 
} 

此使用的線程的固定數(通常是CPU線程的計數)。如果V.size()不止於此,則不會同時調用所有任務。他們會等待可用的線程。

如果您不能使用OpenMP,第三方庫和框架可以爲您提供幫助。

0

通過使用不會導致併發性的線程,你是什麼意思?你是否希望所有線程立即在函數指針向量上創建線程,而不是通過循環遍歷V並創建線程?我不認爲這是可能的,很可能其他答案最終會在不同的抽象層次上做同樣的事情。

示例代碼:

#include <iostream> 
#include <vector> 
#include <thread> 
#include <atomic> 

typedef void (*func)(); 

std::atomic<int> atom; 

void f1() { ++atom; } 
void f2() { atom += 5; } 
void f3() { atom -= 3; } 

int main() 
{ 
    using namespace std; 

    vector<func> func_vec = { &f1, &f2, &f3 }; 
    vector<thread> thread_vec; 

    for (func& f : func_vec) 
     thread_vec.emplace_back(std::thread(f)); 

    for (thread& t : thread_vec) 
     t.join(); 

    std::cout << "Atomic : " << atom; 
} 

有可能是一個更好的辦法來填補thread_vec(即迭代在兩個func_vec與thread_vec的大小設置爲func_vec的thread_vec),但是,對於一個例子很好。如果直到主線程執行結束時才需要線程正常結束,則可以完全刪除thread_vec,然後創建一個線程,並立即將其作爲其他答案demonstrated