Boost Threads - Programm schläft ein bei Konsolen minimierung



  • Die Systemauslastung ist nahezu null.

    Nur das Betriebssystem nutzt das OS nutzt den Prozessor ein wenig.

    Prioritäten? Was ich bisher probiert habe ist z.B. dem Prozess die Prioriät Ecthzeit zu geben. Auf Linux entsprechend auch die höchste.

    Es tut sich nichts (bzw. alles sehr sehr langsam), bis ich wie gesagt die Konsole wieder auf und zu mache.

    Bei Linux ohne GUI klappt es nicht. Das ist das Programm allgemein langsam, weil ich es ja nicht maximieren und minimieren kann.



  • An mehreren stellen habe ich mir unsichere Semaphoren gebastelt.

    Beispiel:

    bool semaphore=false;
    thread1()
    {
    
    //lange Rechenaufgabe.....
    
    semaphore=true;
    
    }
    
    thread2()
    {
    
    while(!semaphore) wait(1); //wait in ms
    
    ...
    
    }
    

    Kann das zu solchen blockaden führen?
    Regelt ein modernes Betriebssystem den Speicher nicht so, dass hier keine Fehler entstehen düften?

    An irgendwas muss es ja liegen. würde es was bringen, diese semaphoren durch mutex, daher .lock() und .unlock() zu ersetzen?

    Das Problem ist wirklich komisch.

    Gruß
    WAR][FIRE



  • Kann mir gut vorstellen, dass es etwas ändern könnte - wait() wird ja auch ne minimale-auflösungszeit haben - unter windows sind es glaube ich 17ms - ähnlich wird es in der unix-welt bestimmt auch aussehen...
    und wenn dein programm jetzt jedes mal mehrere ms wartet, wäre es gut möglich, dass ein thread den anderen gerade zufällig immer dann blockiert, wenn dieser wieder deinen billig-semaphore lesen möchte...

    ich würds einfach mal probieren, es zu ändern - sollte ja mit replace-all nicht länger als paar Sekunden dauern...

    bb



  • Problem:

    while(status != 6) wait(1);
    
    ...
    
    while(status != 5) wait(1);
    
    ...
    

    Ich warte bis eine Variable einen bestimmten Wert annimmt. Gibt es in Boost zufällig Semaphoren?

    andere Ideen?

    Komme mit kritischen Bereichen nicht weiter.

    Gruß
    WAR][FIRE



  • http://www.boost.org/doc/libs/1_40_0/doc/html/thread.html

    ich find dort zwar nirgendwo was von semaphores, aber weiß auch nicht, ob das vll nen begriff aus der windows-welt ist und das dort nur anders heißt oder obs das vll nur unter windows gibt...
    aber gibt ja paar alternativen^^

    bb



  • arg ich hätte in der Schule im Englisch Unterricht besser aufpassen sollen.

    Ich probier mal was zu finden. *babelfish nutz*



  • WAR][FIRE schrieb:

    arg ich hätte in der Schule im Englisch Unterricht besser aufpassen sollen.

    das denk ich mir jeden tag 😣
    ganz besonders immer dann, wenn ich die verlegenheit komme, irgendwas auf englisch zu schreiben^^



  • führt es eigentlich zu problemen, wenn zwei Thread eine Variable lesen?



  • WAR][FIRE schrieb:

    führt es eigentlich zu problemen, wenn zwei Thread eine Variable lesen?

    nein



  • unskilled schrieb:

    WAR][FIRE schrieb:

    führt es eigentlich zu problemen, wenn zwei Thread eine Variable lesen?

    nein

    Afaik kann es auch lesend Probleme geben. IIRC hat da Blue-Tiger mal was zu geschrieben.. ich such mal..

    EDIT:
    OK, war ein bisschen anderts. Obwohl man es eigentlich doch in eine ähnliche Problematik nehmen kann.



  • drakon schrieb:

    unskilled schrieb:

    WAR][FIRE schrieb:

    führt es eigentlich zu problemen, wenn zwei Thread eine Variable lesen?

    nein

    Afaik kann es auch lesend Probleme geben. IIRC hat da Blue-Tiger mal was zu geschrieben.. ich such mal..

    hmm... hab ich noch nicht gehört - allerdings ist das auch nicht gerade mein fachgebiet ;o)
    es kann aber definitiv probleme geben, wenn schreibende zugriffe gehen, obwohl das objekt const ist (stichwort mutable)

    bb

    edit: war aber trotzdem interessant, der thread^^



  • An den wait(); Funktionen hat es leider nicht gelegen.

    Aber ich kann evtl. den Fehler weiter eingrenzen:

    In der main Funktion wird ein Objekt1 erstellt.

    In diesem Objekt1 wird ein Thread und ein weiteres Objekt erstellt (Objekt2).

    Wenn der Thread in Objekt1 jetzt eine Methode in Objekt 2 aufruft, sinkt die Geschwindigkeit der Abarbeitung in Objekt2 dramatisch:

    Die Methode in Objekt2 ruft weitere Methoden aus Objekt2 auf.

    Hier gibt es Probleme:

    Methode1(){
    
          Methode2(..);
    }
    
    Methode2(){
    ...
    }
    

    Wenn z.B. der Code in Methode2 abgeabeitet ist, dauert der Sprung zurück in die Methode1 alleine 10 sekunden!!

    Wie kommt sowas???

    Das passiert wie gesagt immer nur wenn die Konsole im Hintergrund ist.

    Gruß
    WAR][FIRE



  • versuch ein minimal-beispiel zu konstruieren, und poste es hier.
    ich glaube nicht dass sich mit deiner erklärung irgendwer konkret vorstellen kann, was du da machst, und wie. ich zumindest kann es nicht.



  • ....Fehler gefunden.

    Es gab Probleme in mehreren Threads mit den kritischen Bereichen (mutex).

    Ich weiß nicht wie es passieren kann, dass ein Thread der schon ewig wartet, keinen Zugriff auf einen mutex bekommt, obwohl im anderen Thread regelmäßig der Bereich freigegeben wird und danach eine Rechenaufgabe durchgeführt wird...

    Wie dem auch sei. Ich habe den blockierenden Thread mit einem 5 ms wait ausgebremmst, so das die anderen auch mal dürfen.

    Zwei Tage gingen dabei drauf und die Lösung bestannt bei mir aus zwei zusätzlichen wait Methoden 😨

    Das derFunktionssprung bei mir 10 sekunden gedauert hat, kann ich mir nur damit erklären, dass ich hier mit einem uralt PC arbeite auf dem vs 2008 installiert ist....

    Gruß
    WAR][FIRE



  • WAR][FIRE schrieb:

    Ich weiß nicht wie es passieren kann, dass ein Thread der schon ewig wartet, keinen Zugriff auf einen mutex bekommt, obwohl im anderen Thread regelmäßig der Bereich freigegeben wird und danach eine Rechenaufgabe durchgeführt wird...

    Wenn die "Mutex" zufälligerweise eine CRITICAL_SECTION ist, dann ist das IIRC sogar dokumentiertes verhalten.

    Wie dem auch sei. Ich habe den blockierenden Thread mit einem 5 ms wait ausgebremmst, so das die anderen auch mal dürfen.

    Sehr unsaubere "Lösung".



  • hustbaer schrieb:

    WAR][FIRE schrieb:

    Ich weiß nicht wie es passieren kann, dass ein Thread der schon ewig wartet, keinen Zugriff auf einen mutex bekommt, obwohl im anderen Thread regelmäßig der Bereich freigegeben wird und danach eine Rechenaufgabe durchgeführt wird...

    Wenn die "Mutex" zufälligerweise eine CRITICAL_SECTION ist, dann ist das IIRC sogar dokumentiertes verhalten.

    Wie dem auch sei. Ich habe den blockierenden Thread mit einem 5 ms wait ausgebremmst, so das die anderen auch mal dürfen.

    Sehr unsaubere "Lösung".

    Hallo hustbaer,

    ich weiß 😞 aber ich bin schonmal froh das ich eine Lösung zum Präsentieren haben. :p

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

    Am besten wären Prioritätsvergaben für mutex.

    Sowas wie:

    mutex.lock(prio_low);
    

    Wenn es sowas geben sollte.

    Gruß
    WAR][FIRE



  • WAR][FIRE schrieb:

    Ich warte bis eine Variable einen bestimmten Wert annimmt. Gibt es in Boost zufällig Semaphoren?

    http://www.boost.org/doc/libs/1_40_0/doc/html/thread/synchronization.html#thread.synchronization.condvar_ref Gibt sogar ein Codebeispiel 🙂

    EDIT: selbstgebaute Mutexe aus reinen bools koennen sehr hart ins Auge gehen! Stell den Code mal um, so dass du Conditional Variables verwendest. Wuerd mich nicht wundern wenn sich dein Problem damit aufloest 🙂

    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?



  • Dieses Beispiel?

    boost::condition_variable cond;
    boost::mutex mut;
    bool data_ready;
    
    void process_data();
    
    void wait_for_data_to_process()
    {
        boost::unique_lock<boost::mutex> lock(mut);
        while(!data_ready)
        {
            cond.wait(lock);
        }
        process_data();
    }
    

    Da kann ich dir bestätigen dass deine Vermutung falsch ist.
    Der Aufruf von cond.wait(lock) verhindert hier effektiv, dass der Compiler den Wert von data_ready in einem Register behält, oder sogar den Zugriff ganz wegoptimiert.
    volatile ist also nicht nötig.



  • 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.


Anmelden zum Antworten