[C++11] Problem mit Nebenläufigkeiten



  • Hi,

    ich habe ein problem mit Nebenläfigkeiten, atomics und mutexes. Es gibt 3 Threads:

    Globale Variable:

    std:atomic_int counter = 0;
    std::atomic_bool flag = false;
    

    Thread 1:

    run() {
        while(...) {
            if (...) 
                counter++;
        }
    }
    

    Thread 2:

    run() {
        while(...) {
            if (counter > 0) 
                flag = true;
    
        }
    }
    

    Thread 3:

    run() {
        while(...) {
            if (flag) {
                flag = false;
                assert(counter > 0);
                counter--;
            }
        }
    }
    

    Der Counter wird NUR in Thread 1 erhöht. Thread 2 schaut, ob er größer als 0 ist und wenn ja wird Thread 3 benachrichtigt und NUR dieser erniedrigt den Counter. Ich habe nun das Problem, dass das assert aus Thread 3 öfters losfeuert. Dies kann ich mir nicht erklären. Wird durch die Benutzung von atomics nicht garantiert, dass Thread 3 den richtigen Wert liest? Oder müsste dieses reduzierte Beispiel theroetisch funktionieren und ich habe den Fehler woanders eingebaut? Fehlt noch ein mutex?

    Viele Grüße



  • if (flag) {        // flag=true, counter=1
                flag = false;  // flag=false, counter=1
                assert(counter > 0);
                // Thread 2: counter=1 also counter>0 =>
                //           flag=true, counter=1
                counter--;     // counter=0, flag=1
            }
            // flag=true, aber counter=0
    


  • Ich denke

    if (flag) {
                assert(counter > 0);
                counter--;           // zuerst dekrementieren
                flag = false;        // dann flag zurücksetzen
            }
    

    sollte funktionieren.

    Kann sein, dass Thread 2 dann das flag zwischendurch einmal auf true setzt aber Thread 3 das nicht merkt (weil der gerade im assert() steckt), sieht bei dir aber nicht so aus, als ob das ein Problem darstellen würde.



  • Danke! Es lag wirklich an einer bestimmten Verzahnung. Dabei dachte ich, dass ich alles einmal durchgegangen wäre... 😮


Anmelden zum Antworten