Meine Thread Klasse (bitte mal testen)



  • Kann den Thread bitte wer löschen damit nicht noch irgendwer auf die Idee kommt den greislichen Horror da oben zu verwenden?



  • @hustaer

    Plassy schrieb:

    ...oder ein paar Kommentare (konstruktive ;)) zu dem Design abgeben könnte.

    😞



  • Was willst du von mir? Du setzt dich über sämtliche Regeln zum Thema Threading hinweg weil du dich in deiner unendlichen Selbstüberschätzung für reichlich schlau hältst, und postest gemeingefährlich falschen Code. Glaubst du nicht wenn es so einfach ginge wäre da vor dir schon jemand draufgekommen? Ja, wäre, und nein, so einfach geht es nicht.

    Konstruktive Kritik: die ganzen "volatile bool" sind alle Blödsinn, das funktioniert so nicht, das führt nur zu bösen race conditions (aka. data races) und im endeffekt dazu dass das ding irgendwann abstürzt oder sonstwie gröber Blödsinn baut.



  • inline unsigned int getNumTasks() const
        {
            while(not mIsAllowedToQueue)
                /* waiting */;
    
            return mNumTasksQueued - mNumTasksRemoved;
        }
    

    solange er nicht die erlaubnis zum queuen hat gibt er was zurück. und was macht er sonst?

    wieso ist eigentlixch not blau. mein VS 2003 kennt kein not.



  • ich sehs. ein ; hinter dem kommentar. 😮 👎



  • not ist auch kein Keyword sondern ein define:

    #define not !
    

    Sollte sich in <iso646.h> befinden.


  • Mod

    hustbaer schrieb:

    not ist auch kein Keyword sondern ein define:

    #define not !
    

    Sollte sich in <iso646.h> befinden.

    not ist ein keyword - Visual C++ hält sich in diesem Punkt nur nicht an den Standard. Es ist in keinem Falle eine schlechte Idee, <ciso646> einzubinden für den Fall der Fälle.



  • hustbaer schrieb:

    Was willst du von mir? Du setzt dich über sämtliche Regeln zum Thema Threading hinweg weil du dich in deiner unendlichen Selbstüberschätzung für reichlich schlau hältst, und postest gemeingefährlich falschen Code. Glaubst du nicht wenn es so einfach ginge wäre da vor dir schon jemand draufgekommen? Ja, wäre, und nein, so einfach geht es nicht.

    lol 😃 du bist ja ein fröhlicher Geselle.

    hustbaer schrieb:

    Konstruktive Kritik: die ganzen "volatile bool" sind alle Blödsinn, das funktioniert so nicht, das führt nur zu bösen race conditions (aka. data races) und im endeffekt dazu dass das ding irgendwann abstürzt oder sonstwie gröber Blödsinn baut.

    Aber trotzdm würde ich doch gerne etwas näher wissen warum das jetzt in diesem fall zu race-conditions führen kann.
    Die ganzen bools waren eigendlich dazu gedacht Das zu verhindern.
    In wie fern funktioniert Das jetzt nicht??

    MfG
    Plassy



  • Plassy schrieb:

    Aber trotzdm würde ich doch gerne etwas näher wissen warum das jetzt in diesem fall zu race-conditions führen kann.
    Die ganzen bools waren eigendlich dazu gedacht Das zu verhindern.
    In wie fern funktioniert Das jetzt nicht??

    Wärend einer der bool Variablen verändert wird, kann ein Threadwechsel auftreten. Dann der Wert in der Boolvariable undefiniert.

    Außderdem. Wer sagt dir, dass nachdem du eine dieser while-Schleifen verlassen hast, nicht direkt der Threadwechsel statt findet. Dann laufen plözlich 2 Threads gleichzeitig.



  • So eine Klasse kann man in der Praxis gar nicht gebrauchen.



  • ProgChild schrieb:

    Wärend einer der bool Variablen verändert wird, kann ein Threadwechsel auftreten. Dann der Wert in der Boolvariable undefiniert.

    Außderdem. Wer sagt dir, dass nachdem du eine dieser while-Schleifen verlassen hast, nicht direkt der Threadwechsel statt findet. Dann laufen plözlich 2 Threads gleichzeitig.

    Danke :D. Das ist doch mal ne konstruktive antwort 👍
    Aber die Werte der bool variablen dürften doch eigendlich nie undefiniert sein.
    Wenn ein thread die Variable schreibt und der andere thread die Variable liest bevor der erste thread zuende geschrieben hat, wäre das doch eigendlich völlig egal da ja nicht der genaue Wert abgefragt wird. Es wird ja nur abgefragt ob die Variable 0 oder nicht 0 ist. Ob am ende irgend ein Datenmüll drin steht dürfte dann doch egal sein, da es nicht 0 und somit "true" wäre. Oder gibts in diesen Fall noch was dazwischen?

    Dein zweites Argument verstehe ich leider nicht so richtig.
    Kannst du das vielleicht noch mal irgendwie anders formullieren?

    MfG
    Plassy



  • nutzlos schrieb:

    So eine Klasse kann man in der Praxis gar nicht gebrauchen.

    Und wieso nicht...??
    Ist Das jetzt auf die Funktion bezogen oder auf die Umsetzung?



  • Plassy schrieb:

    nutzlos schrieb:

    So eine Klasse kann man in der Praxis gar nicht gebrauchen.

    Und wieso nicht...??
    Ist Das jetzt auf die Funktion bezogen oder auf die Umsetzung?

    Hallo Plassy,

    Eine race-condition kann genau dann auftreten, wenn einer der Thread unmittelbar hinter der Schleife

    while(not mIsAllowedToQueue) // bzw. while(mIsQueuing)
                /* waiting */;
    

    unterbrochen wird und der andere Thread jetzt weiterläuft. Das Flag, was Die Sperrung des Bereichs markiert - also entweder 'mIsQueuing' bzw. 'mIsAllowedToQueue' - ist dann noch nicht gesetzt. Dann rennt der zweite Thread in den anscheinend geschützten Bereich, wird womöglich selber unterbrochen, dann kommt wieder der andere dran .. und die race-condition ist da.

    .. es gibt noch einen Grund. Das betrifft die Art und Weise, wie Du wartest. Du tust das in der schon erwähnten Schleife, die lediglich auf die Änderung eines bool-Wertes reagiert. Das klappt i.A. wenn Dein Programm mit den zwei Threads das einzige - oder fast das einzige - auf dem Rechner ist. Wenn Du das Verfahren in mehr als einem Thread machst und/oder die CPU-Last hoch geht, dann kann es schon passieren, dass Deine CPU sich zu mehreren 10% nur noch in diesen Schleifen tollt. Auf die Performance des Gesamtsystems wirkt sich das furchtbar aus.

    Schau Dir vielleicht mal dies hier an. Ich verwende da zwar nur einen int-Wert als Kommando aber grundsätzlich könnte man den Kommando-Typ auch durch ein boost::function<void> ersetzen. Dann wäre man völlig flexibel.

    Gruß
    Werner



  • ProgChild schrieb:

    Wärend einer der bool Variablen verändert wird, kann ein Threadwechsel auftreten. Dann der Wert in der Boolvariable undefiniert.

    Aber nur theoretisch. Ein bool ist ein Byte, das schreibt man in einer Instruktion, da kann also kein Threadwechsel dazwischenfunken.



  • @Werner Salomon

    Hey danke, Das sieht wirklich gut aus.
    Ich habe noch eine zweite Version der Klasse die ich auch mit nem mutex schütze.
    Aber dein code wirkt doch etwas edler ;).
    Ich werde mich dann wohl an dein Beispiel halten.

    Was mich aber auf die Idee gebracht hat das ohne system-lock Befehle
    zu realisieren war dieser Artikel:

    Lock-free Interprocess Communication
    http://www.ddj.com/cpp/189401457

    Ich habe das Prinzip dann so abgeändert, dass es zu meinem Problem passt.
    Aber vielleicht habe ich auch was falsch verstanden??

    Noch was zu deiner Klasse...

    // -- Members
    boost::mutex m_guard;
    boost::condition m_signal;
    std::queue< Cmd > m_input;
    boost::thread m_thrd;       // MUSS hier letztes Member sein!
    

    Wiso muss "m_thrd" der letzte member sein??
    Und danke nochmal 👍.

    MfG
    Plassy



  • Bashar schrieb:

    ProgChild schrieb:

    Wärend einer der bool Variablen verändert wird, kann ein Threadwechsel auftreten. Dann der Wert in der Boolvariable undefiniert.

    Aber nur theoretisch. Ein bool ist ein Byte, das schreibt man in einer Instruktion, da kann also kein Threadwechsel dazwischenfunken.

    Nicht nur theoretisch, sondern auch praktisch kann dabei was schief gehen. Und je nach Belastung wird es auch realistischer, Thread 1 prüft den boolwert / Threadsprung / Thread 2 schreibt boolwert. Und schon hast du das Problem.

    Und ich wäre ziemlich vorsichtig zu der aussage mit einer Instruktion sofern es nicht als atomare Instruktion definitiv verankert ist. Vielleicht ist mein Verständnis hier etwas mager aber wenn ich folgendes schreibe:

    ...
    bool a;
    ...
    a = true;
    ...
    

    Kann meines erachtens in der Zeile "a = true" mehr als eine Instruktion verbraten werden (Sorry, ich hatte vor langer Zeit Assembler und keine Ahnung ob das so unbedingt stimmt):

    1. Speicherzelle in das Register laden
    2. Register ändern
    3. Registerinhalt in Speicher zurückschreiben

    cu André



  • Und was heute vielleicht praktisch kein Problem ist, kann Morgen eins sein. Deshalb lieber sauber coden und die Betriebssystemmittel nutzen, die man bereitgestellt bekommt.



  • würd gern meine threadklasse reinhaun, da wird schön mit events und critical section gearbeitet.. aber nachher werden doch dinge gefunden die mein stolz auf die klasse zerstören 😃 😃



  • Plassy schrieb:

    Simon2 schrieb:

    Plassy schrieb:

    ...Ich habe Das jetzt so implementiert, dass es ohne mutexes und system-lock Aufrufe auskommt...

    Das wird lustig !

    Gruß,

    Simon2.

    Deswegen ist es ja auch in einer Klasse gekapselt.

    Sag' ich ja: Wenn Du meinst "Klasse kapseln" hätte irgendeinen "threadtechnischen Effekt" (und würde gar Mutexes oder "System locks" überflüssig machen") .... wird's lustig.

    Das ist so als würdest Du sagen: "Mein Auto kann gar nicht gegen den Baum fahren, weil ja mein Gepäck im Koffer und nicht lose auf den Sitzen liegt"...

    Gruß,

    Simon2.



  • asc schrieb:

    Nicht nur theoretisch, sondern auch praktisch kann dabei was schief gehen. Und je nach Belastung wird es auch realistischer, Thread 1 prüft den boolwert / Threadsprung / Thread 2 schreibt boolwert. Und schon hast du das Problem.

    Die Behauptung war, dass während des Schreibens etwas schiefgehen kann. Nicht zwischen Prüfen und Schreiben.

    Kann meines erachtens in der Zeile "a = true" mehr als eine Instruktion verbraten werden (Sorry, ich hatte vor langer Zeit Assembler und keine Ahnung ob das so unbedingt stimmt):

    1. Speicherzelle in das Register laden
    2. Register ändern
    3. Registerinhalt in Speicher zurückschreiben

    Schritt 1 ist unnötig (sonst hätten wir keine reine Schreiboperation). Das Register ist Thread-lokal, also kann von 2 nach 3 auch nicht schiefgehen.


Anmelden zum Antworten