[sync] eine weitere threrad synchronisierungsfrage



  • Hallo
    Annahme: ich muss zum Zeitpunkt t genau x Prozesse synchronisieren. Um das Problem zu beschreiben liefert die Methode einen dummy Wert.

    Bisherige Lösung (stark abstahiert):

    ...
    Manager::Manager() : syncCounter(0) {}
    ...
    int Manager::sync()
    {
       boost::mutex::scoped_lock lock(syncMutex);
       syncCounter++;
       if( syncCounter< nofCalcClients )  
       {
          syncOnlyWaitCond.wait(lock);
       }
       else //syncCounter==nofCalcClients
       {
          syncCounter = 0;
          syncWaitCond.notify_all();
       }
    
       return syncCounter;
    }
    ///////////////////////////
    int main()
    {
       ...
       for(int t=0; t<1000; t++)
       {
          ...
          manager.sync()
       }
       return 0;
    }
    

    das klappt soweit auch. aber ich habe dennoch bedenken:
    Annahme:
    50 clients syncen
    -> 50 haben sync aufgerufen
    -> der 50. ruft notify_all() auf
    -> 47 clients kehren aus sync zurück
    -> bevor nr 48 sync verläßt ist bereits wieder einer der clients, die bereits zurückgekehrt sind erneut in sync (also quasi einer oder mehrere der 47)
    -> der rückgabewert von 48 ist u.U. nicht "0", weil der klassenmemberzähler bereits verändert wurde (z.B. 1)

    kann das passieren?
    wie vermeide ich das am geschicktesten?



  • Ich glaube auch, dass das von Dir beschriebene Problem auftreten kann. Aus dem Code und der Beschreibung Deiner Anforderung würde ich vermuten, dass das Konstrukt boost::barrier besser für diese Aufgabe geeignet ist. Nach der Beschreibung tut boost::barrier exakt das, was Du hier mit der condition und dem syncCounter versuchst.

    Ich habe schon einiges mit Multithreading und boost::thread gemacht, aber keine Erfahrung mit barrier. Für welche Anwendungen benötigt man so etwas eigentlich?

    Gruß
    Werner



  • naja, barriers kenne ich von MPI. und da heißt es schon: wenn man barriers im code benutzt, dann stimmt was mit dem design nicht (was daran, liegt, dass es hier ja nur um reinen daten austausch geht und man eben mit hilfe der blockenden send/receive-methoden das syncen bewerkstelligen sollte).

    jedenfalls war das wie gesagt ein simple doof beispiel. natürlich mache ich etwas beim syncen und sobald der erste client die methode betritt kann er schon loslegen (wenn er warten würde bis alle in der methode sind, dann kostet das performance und zudem muss man dann dennoch den folgenden bereich schützen, da mit klassenatrributen hantiert wird).


Anmelden zum Antworten