wxWidgets: wxThreads verwenden



  • Hallo,

    Kurze Einleitung worum es geht:
    Ich schreibe gerade an einem Tool, welches beliebige Geometrien aus zusammengesetzten Oberflächen (Kugel, Ebene, Torus, Kegel usw.) analysiert. Als kurzes Beispiel:

    Ein Zylinder:
    Zylindermantel; 2 Ebenen. Der eingeschlossene Bereich der 2 Ebenen mit dem Zylindermantel ergibt einen Zylinder.

    Die Objekte können beliebig komplex werden. Ich habe dazu einen aufwändigen (und sicher nicht idealen) Algorithmus geschrieben, welcher den Raum abscannt und Objekte die größer als 10µm sind aufspüren kann. Mein virtuelles Meßlabor ist 40m x 40m x 40m groß. Ich habe den Raum in Raster zerlegt und schonmal die notwendigen Berechnungen von 64 000 000 000 000 auf wenige Millionen reduzieren können. Dennoch benötigt das Programm, je nach Komplexität des Objektes Bruchteile von Sekunden bis hin zu einigen Minuten.

    Aus diesem Grund muss ich die Berechnung auslagern, um das Programm ansprechbar zu belassen. Leider sind in dem Algorithmus auch viele Aufrufe zu anderen Klassen notwendig. Es würden aber niemals gleichzeitig verschiedene Threads auf 1 Klasse zugreifen.

    Nun meine Frage: Kann ich mit wxThread verwirklichen, ohne den Algorithmus neu schreiben zu müssen, dass eigentlich nur die Berechnung extern gehandhabt wird, mein Programm unter Windows aber nicht mehr als "Programm reagiert nicht" dargestellt wird, sondern einfach eine Messagebox mit "bitte warten, Berechnung im Gang" mit Abbruchsmöglichkeit.

    Das nächste ist, dass ich eine Textfile als Inputfile für ein externes Programm verwende, dieses Programm in der Shell starten lasse und warte, bis dieses mir ein Textfile produziert, welches ich wiederum einlese und nach bestimmten Daten durchsuche.

    Für diesen Fall nehme ich auch an, dass ich das mit wxThread vermutlich realisieren kann.

    Es geht mir jetzt gar nicht so sehr darum, dass mir jemand hilft, dies explizit zu verwirklichen, nur welche Bedingungen tatsächlich daran geknüpft sind, soetwas auf relativ einfachem Weg zu schaffen.

    Vielen lieben Dank,
    dioskur



  • Du kannst natürlich so viele Threads aufmachen wie du möchtest für die Berechnung, wichtig ist nur eines: Mach hin und wieder ein wxSleep mit 2-3ms, damit sollte sich das Problem mit dem "reagiert nicht mehr" behoben sein. Dann würde ich das Programm einfach einfrieren über http://docs.wxwidgets.org/stable/wx_wxwindow.html#wxwindowfreeze oder halt einen Fortschrittsbalken anzeigen.



  • Du brauchst kein Sleep.

    Das nicht reagieren hat ja nichts mit der Hohen CPU-Last zu tun, sondern einfach damit dass du die Message-Queue blockierst.

    Ein wxYield() reicht da schon um das Blockieren, und damit das "Reagiert nicht" loszuwerden.

    Du kannst natürlich auch wxThread verweden, was ich persönlich sauberer finde als das rumgeyielde.

    Was den externen Prozess angeht, schau dir mal wxExecute/wxProcess an. Ich bin gerade dabei eine Gui für Mercurial zu schreiben. Dort verwende ich wxExecute um die HG-Kommandos auszuführen. Ist soweit recht praktisch, weil der Prozess Asynchron laufen kann und wx sich um das Abfangen von stdout und stderr kümmert.


  • Mod

    Hm, schau dir mal dies an: http://wxforum.shadonet.com/viewtopic.php?t=19315

    Sowie solltest du dich evtl. mal über Map Reduce Algorithm infomieren.

    Wenn jede Berechnung sowieso atomar ist, kannst du natürlich auch das in einem einzigen thread machen, welcher dann wieder an dein Fenster eine Nachricht/Event schickt.
    Wenn du mehrere Objekte hast, kannst du aber auch für jedes einen Thread erstellen.

    Wobei viele Threads nicht zwangsweise die Berechnung beschleunigen müssen, das hängt auch immer von der Hardware ab (ein/mehrere Kerne, etc.)



  • Hallo,

    Danke für die Infos, werde mir das alles in Ruhe durchlesen. An sich ist die Berechnungszeit nicht so wichtig (das im Anschluss ausgeführte Programm braucht sowieso mehrere Minuten als Monte Carlo Simulation), es geht eigentlich nur darum, dass das Programm eben steuerbar bleibt. Zeitlich wird man bei meinen Berechnungen nie in den Streß kommen und auch niemals soviele Berechnungen auf einmal durchführen müssen.

    Ich werde mir erst einmal das Yield() ansehen, ich denke das ist sogar ausreichend und mir für zukünftige Applikationen auf jeden Fall Threads allgemein anlernen.

    Besten Gruß,
    dioskur


Anmelden zum Antworten