Boost Threads - Programm schläft ein bei Konsolen minimierung



  • WAR][FIRE schrieb:

    Hast du evtl. eine schönere Lösung?

    Vermutlich hätte ich eine schönere Lösung, wenn ich etwas genauer wüsste, was du da eigentlich machen willst.
    Kannst du ein kleines Beispiel posten? Aber bitte nicht 2-3 Zeilen, sondern so dass alles relevante drinnen ist, dass man erkennen kann wozu dieses etwas seltsame lock/unlock Muster gedacht ist etc.

    Oder du beschreibst das was du eigentlich machen wolltest. Also was "was", und nicht das "wie".


  • Mod

    Blue-Tiger schrieb:

    EDIT2: wobei ich das Codebeispiel in der Boost-Doku nicht ganz korrekt finde. IMHO muesste die bool-Variable "volatile" sein, damit der Compiler nicht in Versuchung kommt, den Zugriff darauf in der while-Schleife wegzuoptimieren. Kann mir das wer mit mehr Ahnung bestaetigen?

    volatile ist weder notwendig noch würde es im schlimmsten Fall helfen.
    Solange der Compiler nicht beweisen kann, dass data_ready aliasfrei ist (bei Objekten mit extern linkage müsste man das gesamte Programm analysieren), oder er den gesamten Code in cond.wait kennt (praktisch ausgeschlossen, hier sind an irgendeiner Stelle immer Assemblerroutinen oder Systemaufrufe im Spiel), muss er davon ausgehen, dass der Aufruf cond.wait(look) den Zustand von data_ready möglicherweise verändert. Hier die Abfrage wegzuoptimieren genügt dann aber der as-if-Regel nicht mehr.
    Umgekehrt nützt volatile dann auch nichts, wenn die Abfrage ohne wegoptimiert würde. volatile hat an dieser Stelle nichts verloren - in den Fällen, in denen es zu helfen scheint, fehlt in der Regel eine Schreib-/Lesebarriere.



  • Gerne:

    Was wird gemacht:

    Es wird ein Industrieroboter angesteuert, der einen permanenten Kommunikationsaustausch fordert. Deswegen musste ein Thread erstellt werden, der dies realisiert.

    Weiter müssen dem Roboter Befehle mitgeteilt werden. Diese Befehle müssen in die Kommunikationsschleife eingebracht werden.

    Daher: Eine Methode muss in den Thread eingreifen und Befehlsdaten übermitteln.

    Dafür wurden mutexe eingesetzt:

    //Das ist der Kommunikationtionsthread, der permanent sendet und empfängt.
    //Hier war das Problem, dass bei einem unlock() direkt wieder ein lock() 
    //ansteht. Das hat die Methode nicht zugreifen lassen bzw. schon, wenn die 
    //Konsole im Vordergrund war?!?!?!?
    foo::thread()
    {
         while(true)
         {
              mutex.lock();
    
              senden(daten);
    
              empfangen(...)
    
              mutex.unlock();
              wait(5); //Dieses wait() löst das Problem (unsauber)
         }
    }
    
    foo::methode()//Diese Methode muss Daten (Befehle) in den Kommunikationsthread einbringen 
    {
         mutex.lock();
         daten = 5;
         mutex.unlock();
    }
    

    Der Kommunikationsthread arbeitet mit den "daten". Daher müssen diese synchronisiert werden.

    Ja ich hoffe das macht das Problem deutlich. Wäre gut wenn es dafür eine saubere Lösung gibt. Waits gefallen mir auch nicht wirklich.

    Gruß
    WAR][FIRE



  • naja man könnte es zum bleistift so machen:

    foo::thread() 
    { 
         mutex.lock(); 
         while(true) 
         { 
              TYP lokale_kopie = daten;
              mutex.unlock(); 
    
              senden(lokale_kopie); 
              TYP2 e = empfangen();
    
              mutex.lock(); 
              trallala = e;
         } 
         mutex.unlock(); 
    } 
    
    foo::methode()//Diese Methode muss Daten (Befehle) in den Kommunikationsthread einbringen 
    { 
         mutex.lock(); 
         daten = 5; 
         mutex.unlock(); 
    }
    

    sollte das aus irgendeinem grund nicht gehen, schreib bitte ein beispiel bzw. eine erklärung die ausreichend ist, um zu verstehen, wieso es nicht geht 🙂



  • camper schrieb:

    Solange der Compiler nicht beweisen kann, dass data_ready aliasfrei ist (bei Objekten mit extern linkage müsste man das gesamte Programm analysieren), ...

    ... und bei Objekten mit internal linkage bzw. sogar lokalen Variablen, gibt es nur zwei Möglichkeiten:

    a) entweder der Thread hat überhaupt garkeine Möglichkeit die Variable zu modifizieren (weil er die Adresse nicht kennt), oder
    b) die Adresse der Variable muss irgendwo "an den Thread übergeben" worden sein

    a) ist ja kein Problem, und im Fall b) muss der Compiler zu dem Schluss kommen, dass ein Alias auf die Variable existieren könnte.



  • @hustbaer & camper: thx fuer die Aufklaerung 🙂



  • Danke huste hustbaer!

    Wurde so umgesetzt 🙂

    Gruß
    WAR][FIRE


Anmelden zum Antworten