Frage

habe ich ein Single-Threaded-Linux-App, die Ich mag würde parallel machen. Er liest eine Datendatei, erstellt Objekte und platziert sie in einem Vektor. Dann ruft es ein rechenintensive Verfahren (+ 0,5 Sekunden) für jedes Objekt. Ich möchte das Verfahren parallel zu der Objekterstellung nennen. Während ich in qt und TBB geschaut habe, bin ich auf andere Optionen offen.

Ich wollte den Thread starten (s), während der Vektor leer war. Jeder würde nennen makeSolids (unten), die eine while-Schleife hat, die bis interpDone == true und alle Objekte im Vektor laufen würde verarbeitet wurden. Aber ich bin ein n00b, wenn es um Threading kommt, und ich habe für eine fertige Lösung.

QtConcurrent::map(Iter begin,Iter end,function()) sieht sehr einfach, aber ich kann es nicht auf einen Vektor verwenden, die in der Größe ändert sich, kann ich? Und wie würde ich ihm sagen, um weitere Daten zu warten?

ich auch bei Intel TBB aussehen, aber es sah aus wie mein Haupt-Thread würde halt, wenn ich verwenden parallel_for oder parallel_while. Dass stinkt, da ihr Speichermanager empfohlen wurde (offene Kaskade der mmgt schlechte Leistung hat, wenn multithreaded).

/**intended to be called by a thread
\param start the first item to get from the vector
\param skip how many to skip over (4 for 4 threads)
*/
void g2m::makeSolids(uint start, uint incr) {
  uint curr = start;
  while ((!interpDone) || (lineVector.size() > curr)) {
    if (lineVector.size() > curr) {
      if (lineVector[curr]->isMotion()) {
        ((canonMotion*)lineVector[curr])->setSolidMode(SWEPT);
        ((canonMotion*)lineVector[curr])->computeSolid();
      }
      lineVector[curr]->setDispMode(BEST);
      lineVector[curr]->display();

      curr += incr;
    } else {
      uio::sleep(); //wait a little bit for interp
    }
  }
}

EDIT: Um es zusammenzufassen, was ist der einfachste Weg, um einen Vektor zur gleichen Zeit zu verarbeiten, dass der Haupt-Thread des Vektors ist bevölkern

War es hilfreich?

Lösung

Es ist schwer zu sagen, wenn Sie denken über dieses Problem gewesen tief und es gibt mehr, als Sie auf einlassen, oder wenn Sie nur über sie denken sind, oder wenn Sie nur vorsichtig Threading sind.

, um die Datei zu lesen und die Erstellung von Objekten ist schnell; das ein Verfahren ist langsam. Die Abhängigkeit ist jeweils aufeinander folgender Ctor auf dem Ergebnis des vorherigen Ctor abhängt - ein wenig seltsam - aber ansonsten gibt es keine Datenintegrität Probleme, so gibt es nichts zu sein scheint, dass der Bedarf von mutexes und so geschützt werden

.

Warum ist dies komplizierter, als so etwas wie diese (in rohem Pseudo-Code):

while (! eof)
{
    readfile;
    object O(data);
    push_back(O);
    pthread_create(...., O, makeSolid);
}


while(x < vector.size())
{
    pthread_join();
    x++;
}

Wenn Sie eine Schleife nicht wollen, auf die in der Haupt schließt sich dann aus einem Thread laichen auf sie zu warten, um einen Vektor von TIDs vorbei.

Wenn die Anzahl der erstellten Objekte / Threads verrückt ist, einen Thread-Pool verwenden. Oder einen Zähler setzen ist die Schaffung Schleife die Anzahl der Threads zu beschränken, die vor dem Ausführen von denen verbunden sind, geschaffen werden können.

Andere Tipps

Zum einen profitieren von Threading Sie ähnlich langsame Aufgaben für jeden Thread zu tun finden müssen. Sie sagten, Ihre pro-Objektverarbeitung nimmt .5s +, wie lange die Dateien lesen / Objekterstellung nehmen? Es könnte leicht ein Zehntel oder ein Tausendstel jener Zeit sein, in welchem ??Fall Ihres Multithreading-Ansatz vernachlässigbare Nutzen produzieren wird. Wenn das der Fall ist, (ja, werde ich Ihre ursprüngliche Frage bald beantworten einhüllen es nicht), dann denken Sie mehrere Objekte gleichzeitig zu verarbeiten. Angesichts Ihrer Verarbeitung dauert eine ganze Weile, die Thread-Erzeugung ist Aufwand nicht sehr bedeutend, so dass Sie einfach Ihre Hauptdatei Lese / Objekterstellung Thread laichen einen neuen Thread haben könnten und leiten sie an dem neu geschaffene Objekt. Der Haupt-Thread fährt dann das Lese / nachfolgende Objekte zu schaffen. Nachdem alle Objekte Lese- / erstellt wurde, und alle Verarbeitungsthreads gestartet, „schließt sich“ der Haupt-Thread (wartet) den Arbeitsthreads. Wenn dies zu viele Threads erstellen wird (in Tausend), dann legt eine Grenze, wie weit vor dem Haupt-Thread ist erlaubt zu bekommen: es könnte lesen / erstellen 10 Objekte dann 5 verbinden, dann lesen / erstellen 10, an 10, lesen / erstellen 10, verbindet 10 usw. bis zum fertigen.

Nun, wenn Sie wirklich die lesen wollen / erstellen mit der Verarbeitung parallel zu sein, aber die Verarbeitung serialisiert wird, dann können Sie immer noch den oben beschriebenen Ansatz verwenden, aber nach jedem Objekt verbinden. Das sind irgendwie seltsam, wenn Sie entwerfen das mit nur diesem Ansatz im Auge, aber gut, weil man leicht mit der Objektverarbeitung Parallelität oben als auch experimentieren können.

Alternativ können Sie auch einen komplexeren Ansatz verwenden, der nur den Haupt-Thread beinhaltet (dh das Betriebssystem erstellt, wenn Ihr Programm beginnt), und einen einzelnen Worker-Thread, dass der Haupt-Thread beginnen. Sie sollten mit einem Mutex koordiniert werden (ein Variable Gewährleistung gegenseitig ausschließenden, das heißt, nicht-gleichzeitiger Zugriff auf Daten), und eine Bedingungsvariable, die den Arbeiter-Thread ermöglicht, effizient blockieren, bis der Haupt-Thread mehr Arbeit zur Verfügung gestellt hat. Die Begriffe - Mutex und Zustandsgröße -. Die Standardbedingungen im POSIX Threading sind, dass Linux verwendet, so bei der Erläuterung der einzelnen Bibliotheken verwendet werden, sollten Sie interessiert sind Summarisch, der Arbeiter-Thread wartet, bis die Haupt Lese- / erstellen Thread Sendungen es ein Wecksignal ein anderes Objekt angibt, ist zur Verarbeitung bereit. Sie können einen Zähler mit dem Index des letzten vollständig erstellt, ready-for-Verarbeitung Objekt haben wollen, so der Arbeiter-Thread es die Anzahl der bearbeiteten Objekte und bewegen sich entlang der bereit diejenigen, bevor erneut die Zustandsgröße Kontrolle halten kann.

@Caleb: recht - vielleicht sollte ich betont habe Aktiv Fäden. Der GUI-Thread sollte immer eine in Betracht gezogen werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top