C++, Threads und GUI



  • Guten Tag, werte Kollegen. Ich möchte mich dieses Wochenende einmal endlich mit der Welt der parallelen Codeausführung beschäftigen. Seit C++11 haben ja nun die Threads Einzug in die C++ Standardbibliothek gefunden. Ferner bietet Intel eine kommerzielle Biblitothek an (TBB), von der eine Untermenge von Microsoft unter dem Namen der PPL angeboten wird, wenn ich das richtig verstanden habe. Da ich mich einen Großteil meiner Zeit mit GUI-Anwendungen auf Windows-Basis beschäftige, wäre entsprechender Support zum Umgang mit GUI's sehr erfreulich. Den C++ threads geht ja nun die Funktionalität ab, die bei den OS-Frameworks unter Invoke und InvokeBegin firmieren, nämlich der expliziten Ausführung im GUI-Thread einer Anwendung, was für mich natürlich sehr wichtig ist. Ansonsten sind sie natürlich sehr "simpel" gestrickt und würden sich meiner ersten Meinung nach hervorragend für die ersten Schritte eignen. PPL wäre wieder Microsoft-abhängig und TBB kostet extra Asche.
    Was wäre denn Eure Empfehlung für eine C++-Thread-Bibliothek? In der Standard-Variante müsste ich ja irgendwie diese Invoke-Funktionalität mit Hilfe von PostMessage und Lambdas (zumindest ist das das einzige, was mir einfällt) zusammenfrickeln, aber würde mich natürlich nicht sofort auf eine spezielle Plattform einschießen, wie das mit PPL der Fall wäre. Aber vielleicht sind die anderen beiden genannten Bibliotheken ja für einen C++-Entwickler so toll, dass man die Abhängigkeiten verschmerzen kann.

    Daher meine Frage an euch: Mit Hilfe welcher C++-Bibliotheken würdet ihr euch als "eigentlich-Windows-aber-vielleicht-auch-mal-mehr"-C++-Programmierer ans Threading für GUI-Anwendungen machen?

    Viele Grüße,
    Deci

    PS: Es tut mir Leid das das hier etwas Windows-bezogen ist, aber meine Intention zielt eher auf C++ im Speziellen und GUI im Allgemeinen ab, denn andersherum. Daher habe ich den Thread hier erstellt.



  • Nach MVC-Model ist die Wahrscheinlichkeit, dass du mit den GUI-Threads rumspielen willst sehr gering.



  • Hrmmm, könntest du das etwas genauer erläutern?
    Ich möchte jetzt natürlich nicht die GUI komplett aus einem anderen Thread "laufen lassen", aber alles an Visualisierung muss ja nun in dem Thread geschehen, der für die entsprechenden Fenster zuständig ist (und im Windows-Fall von einer Message-Pumpe angetrieben wird). Für mich bedeutet das jetzt erst einmal, dass irgendeine Möglichkeit existieren muss, um dem GUI-Thread zu signalisieren, dass da etwas neues ist, das er darstellen könnte. Ich weiß nicht, ob man da auch gut mit Events und irgendwelchen AsynchWait-Funktionen hantieren könnte, aber soweit ich das verstanden habe, wird das hinter der Tür auch über Nachrichten abgefackelt und da fände ich jetzt den "injizierten" Aufruf im Kontext des GUI-Threads irgendwie pflegeleichter, als an allen Ecken und Enden Event-Objekte zu erzeugen.
    Wahrscheinlich befinde ich mich auf dem Holzweg, schließlich mache ich mir ja leider erst die anfänglichen Gedanken. Auf jeden Fall denke ich, sollte ich Deinen Einwand auf jeden Fall besser verstehen!

    Viele Grüße,
    Deci



  • Wenn Du mit UI-Frameworks arbeitest, haben die meistens auch Threading-Bibliotheken, die kann man nutzen. Ansonsten spricht in meinen Augen nichts gegen boost::thread oder std::thread, sofern vorhanden.

    MVC-technisch trennst Du die Verarbeitung der Daten im Hintergrund natürlich von der Anzeige. Um zu signalisieren, dass etwas neues angezeigt werden soll, sind ganz richtig die Events da.

    Event-Objekte brauchst Du nicht erstellen, es gibt in C++ in den UI-Frameworks normalerweise auch ein Signal/Slot-Framework, sodass Du eben Signale feuern kannst, die an bestimmte Slots (Funktionen/Methoden) geknüpft sind. Das ist sauber, weil sich die Eventloop darum kümmert, dass die Events auch zur richtigen Zeit aufgerufen werden.

    Das ist dann aber noch nicht Multithreading, da z.B. das UI einfriert, wenn man im Backend aufwendige Berechnungen macht. Wenn man solche hat, dann sollte man jedoch eben für die Berechnungen Threads erstellen (bzw. asynchrone Funktionsaufrufe, man braucht nicht für alles Threads) und nicht umständlich das UI in einen Thread aushebeln.

    Ohne triftigen Grund ist es aber nicht gut Multithreading anzuwenden, weil die Anwendungskomplexität steigt, die Software in der Regel schwieriger wartbar, änderbar und erweiterbar wird und man eben nichts gewinnt.



  • Hallo Eisflamme!
    Danke für Deine Erläuterungen. Einen solchen Fall, wie du zuletzt beschreibst, überdenke ich gerade. Mein Programm besteht erst einmal aus einem Prozess (gedacht als "Echtzeit" laufendes "Ding", nicht als OS-Prozess). Dieser Prozess läuft hauptsächlich angestoßen durch externe Events und Timer ab. Mein "Problem" (theoretisch) ist zum einen, dass ohne Multithreading die Kapazität dieses Prozess durch einen Kern für immer limitiert ist und (praktisch) zum anderen, dass Darstellungsoperationen und User-Input den Prozess "durchrütteln" (Timer haben ersteinmal immer die niedrigste Priorität und während längeren Zeichenoperationen kann sowieso erst einmal nichts geschehen... ich brauche keine Millisekunden-genauigkeit, aber immerhin möchte ich nicht durch Zeichenoperationen unterbrochen werden) können sowie andersherum genauso. Da ich aber selbst in meinem Notebook vier Kerne habe, dachte ich mir, dass das nicht unbedingt so bleiben muss. Daher wollte ich mir mal anschauen, was man so machen kann und mich mit kleineren Beispielen mal in die Materie einarbeiten, am besten mit einer tollen und modernen C++ Bibliothek, nur dass ich noch nicht ganz beurteilen kann, was von dem großen Angebot nun toll oder gar modern wäre 🙂



  • Mit welcher UI-Bibliothek arbeitest Du denn? QT hat da einige interessante Möglichkeiten.

    Also das Problem ist, dass Dein Prozess nicht flüssig läuft oder wie? Liefert der ständig Ergebnisse, die live angezeigt werden sollen? Oder läuft der länger und die Laufzeit wird in Deinen Augen zu stark durch Benutzereingaben beeinträchtigt?



  • Ich "arbeite" derzeit mit MFC. Also eigentlich benutze ich, was ich aus MFC gebrauchen und ertragen kann und bastele mir ansonsten meinen eigenen C++-Kram zusammen. Mal zu schauen, ob und wie ich das ganze auf Qt portieren könnte steht auch irgendwie auf meiner Agenda, aber das wäre ein ganz schön gewagtes Unterfangen. Das Datenmodell/Dokument etc. macht zwar praktisch überhaupt keinen Gebrauch von dem MFC-Gedöns (Mal von dem Commands abgesehen, die sich wohl schnell auf das Qt-Äquivalent umbiegen ließen). Allerdings benutze ich in der GUI hauptsächlich ein selbst geschriebenes Control - praktisch genau soetwas wie QGraphicsView, das mit Gdi+ oder D2D hantiert. Da ich dort ein eigenes Message-Routing verwende (erlaubt Mixins, lauschen an anderen Fenstern, "Bouncing"-Nachrichten etc.), weiß ich nicht, ob ich das ganze wirklich so problemlos mit dem GraphicsView ersetzen könnte (Vielleicht weißt Du, ob man sich da ein eigenes Routing/Messages implementieren kann?). Und der größte Teil meines Programms verlässt sich auf dieses System bzw. wiederum dessen Basis. Ob ich das so schnell in Qt reingefriemelt bekäme, ist fraglich (Und wie das dann performance-technisch aussieht, wobei ich mir das nicht kritisch vorstelle).

    Aus genannten Gründen wäre für mich wohl erstmal eine Lösung angenehmer, bei der ich auf kein GUI-Framework angewiesen bin.



  • Hrmmm, also ich habe mal den Tag damit verbracht mir Qt etwas anzuschauen, sowie ein paar Beispiele mit der Asynchronous Agent Library von M$ (scheint wohl eine Koproduktion mit Intel gewesen zu sein?) zu basteln.

    Qt: Wie steht's damit denn so, nachdem die Sparte mal wieder den Besitzer gewechselt hat? Da wird es doch bestimmt irgendwann wieder sehr dünne mit der LGPL und dem Support, wenn die Entwicklung nicht zwischendurch erstmal sowieso brachliegt?

    Und die AAL fand ich ja schonmal sehr nett. Nur ein paar Zeilen und schon hat man die CPU auf 100% 😃 Leider habe ich erst einmal nur ein feineres datenfluss-modell, das ich damit umsetzen könnte, für das die Bibliothek dann doch etwas zuviel overhead produziert, denke ich. Daher werde ich da wohl einen traditionelleren Weg gehen. Aber nichts destotrotz, um solch komfortable Bibliotheken geht's mir 😃


Log in to reply