2012-05-14 28 views
7

我在Mac OS Xcode 4.3.2上使用C++ 11 std :: async使用相同的線程,我的代碼沒有達到並行性。在下面的示例代碼中,我想創建10個新線程。在每個線程中,我想計算輸入變量的平方根並將結果設置爲promise。在主函數中我想顯示從線程計算的結果。我使用策略launch :: async調用std :: async,所以我期望它創建一個新線程(10次)。std :: async使用相同的線程,我的代碼沒有達到並行性。

#include <mutex> 
    #include <future> 
    #include <thread> 
    #include <vector> 
    #include <cmath> 
    #include <iostream> 

    using namespace std; 
    mutex iomutex; 

    void foo(int i, promise<double> &&prms) 
    { 
     this_thread::sleep_for(chrono::seconds(2)); 
     prms.set_value(sqrt(i)); 
     { 
      lock_guard<mutex> lg(iomutex); 
      cout << endl << "thread index=> " << i << ", id=> "<< this_thread::get_id(); 
     } 
    } 

    int main() 
    { 
     { 
      lock_guard<mutex> lg(iomutex); 
      cout << endl << "main thread id=>"<< this_thread::get_id(); 
     } 
     vector<future<double>> futureVec; 
     vector<promise<double>> prmsVec; 

     for (int i = 0; i < 10; ++i) { 
      promise<double> prms; 
      future<double> ftr = prms.get_future(); 
      futureVec.push_back(move(ftr)); 
      prmsVec.push_back(move(prms)); 

      async(launch::async, foo, i, move(prmsVec[i])); 
     } 

     for (auto iter = futureVec.begin(); iter != futureVec.end(); ++iter) { 
      cout << endl << iter->get(); 
     } 

     cout << endl << "done"; 

     return 0; 

    } 

但是,如果我使用std :: thread,那麼我可以實現並行性。

#include <mutex> 
    #include <future> 
    #include <thread> 
    #include <vector> 
    #include <cmath> 
    #include <iostream> 

    using namespace std; 
    mutex iomutex; 

    void foo(int i, promise<double> &&prms) 
    { 
     this_thread::sleep_for(chrono::seconds(2)); 
     prms.set_value(sqrt(i)); 
     { 
      lock_guard<mutex> lg(iomutex); 
      cout << endl << "thread index=> " << i << ", id=> "<< this_thread::get_id(); 
     } 
    } 

    int main() 
    { 
     { 
      lock_guard<mutex> lg(iomutex); 
      cout << endl << "main thread id=>"<< this_thread::get_id(); 
     } 
     vector<future<double>> futureVec; 
     vector<promise<double>> prmsVec; 
     vector<thread> thrdVec; 
     for (int i = 0; i < 10; ++i) { 
      promise<double> prms; 
      future<double> ftr = prms.get_future(); 
      futureVec.push_back(move(ftr)); 
      prmsVec.push_back(move(prms)); 

      thread th(foo, i, move(prmsVec[i])); 
      thrdVec.push_back(move(th)); 
     } 

     for (auto iter = futureVec.begin(); iter != futureVec.end(); ++iter) { 
      cout << endl << iter->get(); 
     } 
     for (int i = 0; i < 10; ++i) { 
      thrdVec[i].join(); 
     } 
     cout << endl << "done"; 

     return 0; 

    } 
+0

的'在舊GCCS thread'庫的實現是不是真的功能調用它。嘗試一些非古老的東西。 – pmr

+0

@pmr:我認爲Clang是Xcode 4.2+中的默認編譯器? – ildjarn

+0

@ildjarn當然你是對的。我誤以爲4.3.2意味着一個gcc版本(XCode長時間使用gcc 4.something)。 – pmr

回答

16
  async(launch::async, foo, i, move(prmsVec[i])); 

此行返回future但是因爲你不把它分配給任何未來的析構函數的聲明,結束該塊,並等待結果通過調用std::future::wait()

爲什麼運行無論如何,你是否會手動撥打電話std::async並承諾?異步點在於你不需要手動使用承諾,這是在你的內部完成的。

重寫你foo()返回double然後用async

#include <mutex> 
#include <future> 
#include <thread> 
#include <vector> 
#include <cmath> 
#include <iostream> 

using namespace std; 
mutex iomutex; 

double foo(int i) 
{ 
    this_thread::sleep_for(chrono::seconds(2)); 
    lock_guard<mutex> lg(iomutex); 
    cout << "\nthread index=> " << i << ", id=> "<< this_thread::get_id(); 
    return sqrt(i); 
} 

int main() 
{ 
    cout << "\nmain thread id=>" << this_thread::get_id(); 
    vector<future<double>> futureVec; 

    for (int i = 0; i < 10; ++i) 
     futureVec.push_back(async(launch::async, foo, i)); 

    for (auto& fut : futureVec) 
    { 
     auto x = fut.get(); 
     lock_guard<mutex> lg(iomutex); 
     cout << endl << x; 
    } 

    cout << "\ndone\n"; 
} 
+0

一旦我們在for循環中,它就是順序代碼。這裏不需要互斥。 – Jagannath

+0

我想一起使用Promise和異步。這是否意味着如果我們將Promise與std :: async一起使用,那麼它不能像異步一樣運行,並且總是表現爲同步調用? –

+0

@Jagannath:不,在你等待一個未來的第一次迭代中,有九個線程仍然可以運行並寫入cout。在第二次迭代中,仍然可以有8個線程寫入cout等。(謝謝代碼改進) –

相關問題