std::threads in bestimmter Reihenfolge?
-
happystudent
Ich denke, du kannst die den Thread sparen, wenn du PostMessage(...) -> Asynchron statt SendMessage(...) -> synchron (wartet auf Rückmeldung) verwendest.
-
coder777 schrieb:
happystudent
Ich denke, du kannst die den Thread sparen, wenn du PostMessage(...) -> Asynchron statt SendMessage(...) -> synchron (wartet auf Rückmeldung) verwendest.
Ne,
PostMessagegeht nicht mit Pointer-Parametern...
-
Ne, PostMessage geht nicht mit Pointer-Parametern...
Das stimmt.
-
coder777 schrieb:
Das stimmt.
Ja, das ist das Problem. Sonst würde ich einfach PostMessage verwenden und fertig. Am liebsten hätte ich einen C++ Wrapper um SendMessage, der PostMessage nachbildet. Falls es sowas schon gibt, immer her damit

Darüber hinaus kann ich aber deinen Argumenten nicht folgen:
coder777 schrieb:
1. Entkopplung:
- Der Hintergrund-Thread hat keine Refernzen ins GUI (kann dementsprechen auch ohne GUI oder in einer Konsolenumgebung laufen).
- Egal was der Hintergrund-Thread macht, das GUI bleibt ansprechbar.Das ist bei Events auch gegeben?
coder777 schrieb:
3. Wenn etwas im Hintergrund passiert, sollte es sich in jedem Fall in der GUI wiederspiegeln.
Kann es ja auch mit Events, das schließt sich ja nicht aus?
coder777 schrieb:
2. Ereignissteuerung kann schnell kompliziert werden, besonders im Fehlerfall.
Reine Geschmacksache würde ich sagen. Hab in C# schon viele Event-basierte GUIs gebaut und finde das sehr schön einfach und gut nachvollziehbar.
coder777 schrieb:
1. Je mehr gewartet werden muss, desto langsamer wird es bis hin zur völligen Serialisierung, so dass der Thread keinen Sinn mehr macht (man merkt das womöglich nicht).
Eine Aufgabe dauert so lange wie sie dauert.
Warum soll das keinen Sinn machen? Wenn ich per GUI eine Gebäudeheizung einstellen will kann das mal 1-2 Tage dauern bis der Sollwert erreicht ist - wie definierst du überhaupt das etwas "zu lange" braucht und deswegen keinen Sinn mehr macht?
coder777 schrieb:
2. Deadlock: Je mehr hin und her geht desto wahrscheinlich tritt einer auf.
Macht mMn auch keinen Sinn... Ein Deadlock sollte durch richtige locks o.ä. ausgeschlossen werden, ansonsten hat man halt ein verbuggtes (= falsches) Program erstellt. Falsch wird dadurch ja nicht besser dass es etwas seltener Abstürzt? Ein häufiger Deadlock ist mir sogar lieber als ein extrem seltener, weil das einfacher zu debuggen ist.
-
@happystudent
Die Daten steckt man in die Fensterklasse (über Mutex synchronisiert), und dann schickt man perPostMessagenur noch eine "ich hab was in Liste X eingetragen was verarbeitet gehört" Benachrichtigung.Mach' ich oft so, funktioniert wunderbar.
-
hustbaer schrieb:
@happystudent
Die Daten steckt man in die Fensterklasse (über Mutex synchronisiert), und dann schickt man perPostMessagenur noch eine "ich hab was in Liste X eingetragen was verarbeitet gehört" Benachrichtigung.Hm, aber die Fensterklasse (bzw. das Ganze Fenster) gehört ja zu einem externen Prozess... Dann müsste ich ja erstmal in dem fremden Prozess Speicher allozieren und den string dann entsprechend transportieren...
Den Pointer auf den string könnte ich schon per SendMessage verschicken, aber die Adresse passt dann im Zielprozess halt nicht mehr...
Geht das überhaupt alles, oder war die Lösung eher für Fenster gedacht die sich alle im gleichen Prozess aufhalten?
-
happystudent schrieb:
Geht das überhaupt alles, oder war die Lösung eher für Fenster gedacht die sich alle im gleichen Prozess aufhalten?
Ja, das. Sorry, hatte den gesamten Kontext nicht mehr im Kopf. Bzw. ich bin mir gar nicht sicher ob ich das mit der Teilung in zwei Prozesse überhaupt gelesen habe.
happystudent schrieb:
Dafür benutze ich SendMessage und
WM_SETTEXT, schon seit einiger Zeit und das funktioniert. Leider ist das Ganze sehr langsam wenn der Inhalt der Textbox sehr lang wird (SendMessage ist ja synchron und kann auch nicht abgebrochen werden).
(...)
Berechtigte Angst? Bis jetzt (2 Tage testen) hats imer geklappt aber ich hab ein ungutes Gefühl dabei. Und ist die Lösung die threads quasi hintereinander zu queuen in diesem Kontext sinnvoll oder gibts für so eine Anwendung noch etwas einfacheres/besseres?Ich würde da wohl einfach einen eigenen Hilfsthread machen, der so lange am Leben bleibt wie du
WM_SETTEXTverschicken willst.
Der macht dann im Prinzip:void HelperThread::NotifyTextChanged(std::string const& text) { { unique_lock lock(m_mutex); m_text = text; m_textChanged = true; } m_condition.notify_one(); } void HelperThread::ThreadFn() { unique_lock lock(m_mutex); while (true) { m_condition.wait(lock, [&]{ return m_endThread || m_textChanged; }); if (m_endThread) break; std::string text = m_text; m_textChanged = false; // <---- EDIT lock.unlock(); ::SendMessage(m_targetWindowHandle, WM_SETTEXT, 0, reinterpret_cast<LPARAM>(text.c_str())); lock.lock(); } }Das Ruckeln auf der Sender-Seite muss damit auch weg sein, und du hast immer nur einen Thread und schickst die
WM_SETTEXTauch garantiert in der richtigen Reihenfolge.
Und du hast viel weniger Overhead, da du nicht dauernd neue Threads erzeugst und wieder zerstörst.Höchstens die Empfängerseite kann noch "ruckeln" - wenn die
SendMessageAufrufe zu lange brauchen.Ansonsten kannst du natürlich auch einen Shared-Memory Bereich oder eine Shared Data-Section verwenden wo du den Text reinsteckst. Synchronisiert mit ner named interprocess Mutex (Win32 Mutex oder Boost Interprocess). Und bei Änderung ne Message posten oder nen named EVENT setzen (manual reset Event -- oder auch wieder ne Boost Interprocess Condition Variable).
EDIT: m_textChanged = false; vergessen - ohne das würde der Thread ja unnötigerweise dauernd laufen.
-
hustbaer schrieb:
Ich würde da wohl einfach einen eigenen Hilfsthread machen, der so lange am Leben bleibt wie du
WM_SETTEXTverschicken willst.
Der macht dann im Prinzip:Funktioniert perfekt, besten Dank

Damit läuft das einfach viel smoother als jeden SendMessage synchron zu verschicken (und das detachen der threads war mir zu riskant).
hustbaer schrieb:
Höchstens die Empfängerseite kann noch "ruckeln" - wenn die SendMessage Aufrufe zu lange brauchen.
Das stimmt, bei extrem großen Texten kann man das merken wenn man sehr schnell aus dem Textfeld rausklickt. Macht aber gar nix, hauptsache man kann schön schreiben.
-
Ich hab noch ne fehlende Zeile ergänzt. Vermutlich hast du es eh schon selbst gesehen und gefixt - nur für den Fall dass nicht wollte ich den Thread nochmal hoch bringen.
-
hustbaer schrieb:
Ich hab noch ne fehlende Zeile ergänzt. Vermutlich hast du es eh schon selbst gesehen und gefixt - nur für den Fall dass nicht wollte ich den Thread nochmal hoch bringen.
Jo, das hab ich recht schnell gemerkt weil der thread dann permanent in die Textbox geballert hat und gar nix mehr ging

Bin aber schon ziemlich begeistert wie wenig Code das am Ende geworden ist... hatte da mit wesentlich mehr gerechnet
