Boost: Read- Writelock



  • Hallo Forum,

    ich portiere gerade in einem Programm die Synchronisation von PThread nach Boost::Thread.

    Die Read- und Writelocks machen mir Kopfschmerzen. Mit PThread sehen sie so aus:

    ...
    pthread_rwlock_t configReadWriteLock;
    ...
    
    void Config::configReadLock() {
      pthread_rwlock_rdlock(&configReadWriteLock);
    }
    
    void Config::configWriteLock() {
      pthread_rwlock_wrlock(&configReadWriteLock);
    }
    
    void Config::configUnlock() {
      pthread_rwlock_unlock(&configReadWriteLock);
    }
    

    Wenn andere Funktionen in der Config etwas schreiben oder lesen wollen, rufen sie die entsprechenden Lockfunktionen auf und später jeweils einen Unlock.

    Mit Boost ist das irgendwie nicht so einfach. Man hat sowas:

    boost::shared_mutex configReadWriteLock;
    boost::shared_lock<boost::shared_mutex> readLock;
    boost::unique_lock<boost::shared_mutex> writeLock;
    

    Aber die Locks in Boost sind für Scopes konzipiert und nicht für den globalen Gebrauch. Wenn ich sie in die Lock-Funktionen weiter oben packe, sterben sie nach dem Funktionsaufruf sofort wieder. Ein Hack wäre zwar, sie global inital anzulegen und sofort zu unlocken, aber man darf sie dann nicht mehrmals "locken".
    Schwierig zu erklären ...

    Kann mit jemand trotzdem helfen?

    Danke schon mal.

    Viele Grüße,
    anjohn



  • Ich glaube du missverstehst das. boost::shared_mutex ist das was vorher dein pthread_rwlock_t war den kann man auch manuell locken und unlocken. boost::shared_lock ist hingegen so etwas wie ein scoped lockguard der dir nur die Arbeit des manuellen lockens abnimmt.



  • Für ein echtes Read- und Writelock brauchst du aber ohnehin so etwas wie boost::upgrade_lock

    edit: Diese Aussage war Blödsinn

    Schaue dir das mal an:
    http://stackoverflow.com/questions/989795/example-for-boost-shared-mutex-multiple-reads-one-write



  • Sollte eigentlich einfach so funktionieren: Für Config::configReadLock() nimmst du shared_mutex::lock_shared() für Config::configWriteLock() nimmst du shared_mutex::lock() und für Config::configUnlock() Config::unlock()



  • TNA schrieb:

    Ich glaube du missverstehst das. boost::shared_mutex ist das was vorher dein pthread_rwlock_t war den kann man auch manuell locken und unlocken. boost::shared_lock ist hingegen so etwas wie ein scoped lockguard der dir nur die Arbeit des manuellen lockens abnimmt.

    Ja den Shared Mutex kann ich auch direkt verwenden und lock und unlock auf ihm aufrufen.
    Trotzdem muss ich ja irgendwann mal exklusiven Besitz erlangen. Bisher habe ich dafür nur diese Locks gefunden.

    TNA schrieb:

    Für ein echtes Read- und Writelock brauchst du aber ohnehin so etwas wie boost::upgrade_lock

    Schaue dir das mal an:
    http://stackoverflow.com/questions/989795/example-for-boost-shared-mutex-multiple-reads-one-write

    Ich versteh den Unterschied zwischen dem Unique_lock und dem Upgrade_Lock nicht so recht. Erkläre es mir bitte, die Doku von Boost ist irgendwie kompliziert.



  • TNA schrieb:

    Ich glaube du missverstehst das. boost::shared_mutex ist das was vorher dein pthread_rwlock_t war den kann man auch manuell locken und unlocken. boost::shared_lock ist hingegen so etwas wie ein scoped lockguard der dir nur die Arbeit des manuellen lockens abnimmt.

    Ah, ja doch. Ist es vielleicht doch so einfach:

    void Config::configReadLock() {
      configReadWriteLock.lock_shared();
    }
    
    void Config::configWriteLock() {
      configReadWriteLock.lock();
    }
    
    void Config::configReadUnlock() {
      configReadWriteLock.unlock_shared();
    }
    
    void Config::configWriteUnlock() {
      configReadWriteLock.unlock();
    }
    

    Funktioniert und hängt bisher nicht. Nur, dass ich nun keinen universellen Unlock mehr habe, sondern jeweils einen für Read und Write im Gegensatz zu vorher.



  • Ja, das ist die Lösung die deinem Vorherigen Design am nächsten kommt und sollte funktionieren. Ich kenne mich mit Boost im speziellen auch nicht so besonders aus und musste mich da erst etwas einlesen.



  • Ich habe mir das ganze noch mal durchgelesen und durchdacht. Die moderne c++ Variante wäre vermutlich, wenn die Config einfach Funktionen bieten würde, die ein boost::shared_lockboost::shared\_mutex und ein boost::unique_lockboost::shared\_mutex auf den internen mutex rausreichen, wenn ich mich nicht irre.


Anmelden zum Antworten