Używam C++ 11 na Mac OS Xcode 4.3.2 std :: async używa tego samego wątku i mój kod nie osiąga równoległości. W poniższym przykładowym kodzie chcę utworzyć 10 nowych wątków. W każdym wątku chcę obliczyć pierwiastek kwadratowy zmiennej wejściowej i ustawić wynik w obietnicy. w głównej funkcji chcę wyświetlić wyniki wyliczone z wątków. Wywołuję std :: async z uruchomieniem zasad :: async, więc oczekuję, że utworzy nowy wątek (10 razy).std :: async używa tego samego wątku, a mój kod nie zapewnia równoległości.
#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;
}
Jednak jeśli używam std :: thread, to mogę osiągnąć równoległość.
#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;
}
realizacja 'thread' biblioteki na starszych gccs naprawdę nie jest funkcjonalne. Spróbuj na coś nie-starożytnego. – pmr
@pmr: Myślałem, że Clang był domyślnym kompilatorem w Xcode 4.2+? – ildjarn
@ildjarn Masz rację, oczywiście. Pomyliłem się, że 4.3.2 oznacza wersję gcc (XCode używał gcc 4. coś przez długi czas). – pmr