Seite 1 von 1

Datenaustausch im Betrieb

Verfasst: 31. Juli 2012 12:57
von woody
Hallo ich habe eine interessante Frage:
Angenommen 96 Threads greifen auf dieselbe QMap<int,QList<UserClass*>*>* zu und holen sich bei jedem Zugriff ein QList-Segment mit den UserClass-Objekten.

Interaval-mäßig soll die große QMap neu erstellt werden. Sobald die 2. QMap erstellt ist soll die alte durch die neue ersetzt werden.
Die Frage ist jetzt, wie ich den Austausch sauber über die Bühne bringe, sodass kein Thread-Zugriff fehlschlägt.

Einfach den pointer zuweisen

Code: Alles auswählen

void Class::replace( QMap<int,QList<UserClass*>*>* new)
{
   QMap<int,QList<UserClass*>*>* help_pointer;
   help_pointer = old;
   old = new;
   //delete help_pointer...
}
danke für die hilfe

Re: Datenaustausch im Betrieb

Verfasst: 31. Juli 2012 13:09
von franzf
Zugriffe auf die Map mit EINEM QReadWriteLock schützen. Zum lesen mit einem QReadLocker locken, zum Schreiben (replace) mit einem QWriteLocker.

Re: Datenaustausch im Betrieb

Verfasst: 31. Juli 2012 13:40
von woody
Danke für die Antwort...hilft mir sehr ; )

Re: Datenaustausch im Betrieb

Verfasst: 31. Juli 2012 14:44
von woody
Würde das so funktionieren? Mir ist nur ein bisschen unklar, wie das funktionieren kann, da ja getList und replaceMap völlig verschiedene Methoden sind.

Wenn ein Thread die Methode replaceMap aufruft, werden alle lesenden Threads(getList) geblockt, bis der Write-Lock aufgehoben wird?

Code: Alles auswählen

 QReadWriteLock lock;

 void ReaderThread::run()
 {
     ...
     lock.lockForRead();
     QList<UserClass*>* users = getList(6);
     lock.unlock();
     ...
 }

 void WriterThread::run()
 {
     ...QMap<int,QList<UserClass*>*>* new
     lock.lockForWrite();
     replaceMap(new);
     lock.unlock();
     ...
 }

Re: Datenaustausch im Betrieb

Verfasst: 31. Juli 2012 16:23
von franzf
so sollte es gehen. Aber die Umsetzung ist mindestens schlecht, wenn nicht sogar gefährlich. Du zwingst jetzt den User dazu, selbst zu schützen. Dabei sind doch die beiden FUnktionen darauf ausgelegt, von mehreren Threads angesprochen zu werden. Lock doch dann direkt IN den Funktionen!
Und der Hinweis auf die *Locker-Klassen war nicht weils schön ist, sondern weil die einiges sicherer machen. Manuell nötiges unlocken kann man auch mal vergessen, vor allem wenn du verschiedene Codepfade mit verschiedenen Austrittspunkten hast. Sollte zwischen dem lock() und dem unlock() eine Exception fliegen wird der lock nicht mehr freigegeben. Das nehmen dir die beiden Klassen durch RAII ab.

Re: Datenaustausch im Betrieb

Verfasst: 1. August 2012 09:39
von woody
Danke nochmal für die Hilfe, müsste dann also so korrekt sein:

Code: Alles auswählen


QReadWriteLock lock;

void DataManager::new_users_generated(QHash<QString, User *> *users)
{
    QWriteLocker locker(&lock);
    //delete this->users...
    this->users = users;
}

User* DataManager::getUser(QString user_id)
{
    QReadLocker locker(&lock);
    return users->value(user_id);
}