Std :: async uses the same thread, and my code does not reach parallelism.

I use C ++ 11 on Mac OS Xcode 4.3.2 std :: async uses the same thread and my code does not reach parallelism. In the following code example, I want to create 10 new threads. In each thread, I want to calculate the square root of the input variable and set the result in the promise. In the main function, I want to display the results calculated from threads. I call std :: async with the :: async policy running, so I expect it to create a new thread (10 times).

#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; } 

However, if I use std :: thread, then I can achieve parallelism.

  #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; } 
+7
source share
1 answer
  async(launch::async, foo, i, move(prmsVec[i])); 

This line returns future , but since you are not assigning it to anything, the future destructor runs at the end of the statement, which blocks and waits for the result by calling std::future::wait()

Why do you manually call std::async with a promise when it still returns the future? The point of async is that you do not need to manually use the promise that is made within you.

Rewrite foo() to return a double , then call it with 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"; } 
+16
source

All Articles