2017-11-18 4 views
2

Ich habe eine Funktion, die zufällige URL generiert und versuchen, die Datei herunterzuladen.Wie parallelisiert man eine Funktion, die eine Variable verwendet

void tryURL() 
{ 
    randURL.clear(); 
    for (unsigned short i = 0; i < urlLength; i++) { 
    randURL = randURL + (alphabet[(int)((double)rand()/(RAND_MAX + 1) * alphabetLength)]); 
    } 
    wcout << randURL << endl; 
    HRESULT getImg = URLDownloadToFile(NULL, LPCWSTR((beginURL + randURL + endURL).c_str()), LPCWSTR((randURL + L"/" + endURL).c_str()), 0, NULL); 
    if (SUCCEEDED(getImg)) 
    { 
    wcout << L"Success" << endl; 
    } 
} 

Wenn ich diese Funktion normalerweise ausführen, dann ist es gut funktionieren:

tryURL(); 
0ybOAt 
tryURL(); 
lTPKaR 
tryURL(); 
Ivi05m 
... 

Aber ich brauche in diesem Moment diese Funktion wiederholt Zeiten ausgeführt werden. Ich versuchte dies:

thread threads[10]; 

for (int i = 0; i < 10; ++i) { 
    threads[i] = thread(tryURL); 
} 

for (int i = 0; i < 10; ++i) { 
    threads[i].join(); 
} 

Und es gibt mir immer denselben Wert

0ybOAt0ybOAt 
0ybOAt 

0ybOAt0ybOAt 

0ybOAt 
0ybOAt0ybOAt 
0ybOAt 
0ybOAt 

Und selbst Endl tun ist manchmal nicht angezeigt.

Wie kann ich es beheben? Ich denke, es ist kaputt, weil immer die Variable randURL verwendet wird, aber ich weiß nicht, wie ich das umgehen kann.

Antwort

1

Statt die gleiche Variable verwenden, stellen tryURLreturn die URL:

// assuming that URLs are strings 
std::string tryURL() { /* ... */ } 

Dann einen Vektor von std::future<std::string> erstellen, um die asynchronen Berechnungen darzustellen, die URLs kehrt:

std::vector<std::future<std::string>>> futures; 
futures.reserve(10); 

for (int i = 0; i < 10; ++i) 
{ 
    futures.emplace_back(std::async(std::launch::async, tryURL)); 
} 

Schließlich konsumieren Sie die URLs im Hauptthread:

bieten
+0

Kann diesen Code nicht auf VC17 arbeiten. launch_async wurde durch launch :: async ersetzt, aber consume command not found. Kannst du es reparieren? – megapro17

+0

@ megapro17: 'consume' ist nur ein Beispiel. Das ist, wo deine Logik gehen sollte. –

0

Weitere Fragen auf Stackoverflow einige Hinweise:

Eine einfache Lösung für den rand() Problem ist es, die URL zu erzeugen: s im Hauptthread und Pass sie zum Faden.

void tryURL(std::wstring URL) 
... 
// TODO: Set randURL to a random URL 
threads[i] = thread(tryURL, randURL); 
+0

ok, ich habe den Rand repariert. aber mein Programm läuft nur 4 Threads. Ich kann nicht verstehen warum. Ich habe mehr versucht, aber nur 4 Threads gleichzeitig ausgeführt. Außerdem habe ich 4 Kerne CPU. für (int i = 0; i <100; ++ i) { \t \t \t thr [i] = thread (tryURL); \t \t} – megapro17

Verwandte Themen