Datenaustausch im Betrieb

Du bist neu in der Welt von C++? Dann schau hier herein!
Antworten
woody
Beiträge: 85
Registriert: 1. April 2011 21:13

Datenaustausch im Betrieb

Beitrag 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
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: Datenaustausch im Betrieb

Beitrag von franzf »

Zugriffe auf die Map mit EINEM QReadWriteLock schützen. Zum lesen mit einem QReadLocker locken, zum Schreiben (replace) mit einem QWriteLocker.
woody
Beiträge: 85
Registriert: 1. April 2011 21:13

Re: Datenaustausch im Betrieb

Beitrag von woody »

Danke für die Antwort...hilft mir sehr ; )
woody
Beiträge: 85
Registriert: 1. April 2011 21:13

Re: Datenaustausch im Betrieb

Beitrag 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();
     ...
 }
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: Datenaustausch im Betrieb

Beitrag 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.
woody
Beiträge: 85
Registriert: 1. April 2011 21:13

Re: Datenaustausch im Betrieb

Beitrag 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);
}
Antworten