Seite 1 von 2

Shared Memory zwischen Threads

Verfasst: 25. September 2008 18:35
von diddely
Hi,


Ich habe ein Serial-Objekt, welches Daten von der RS232 Schnittstelle sammelt und sie in der eigenen Instanz (Qlist) abspeichert.

Ich habe einen Master-Thread, welcher diese Daten abholt indem er z.B. mit einem Signal vom Serial-Objekt signalisiert wird. (noch nicht sicher ob ich es so realisiere soll)
Ist Signal Slot bei dieser Anforderung ausreichend?


Diese Daten sollen, je nach Adressat, an den richtigen Worker-Thread weitergeleitet werden.
Daten sind = z.B. eine Struktur welche ein Byte-Array enthält.

Den Master-Thread gibt es nur einmal aber die Worker Threads wird es mehrfach geben. Die Zahl der worker-threads varieren zur Laufzeit.

Mein erster Gedanke war zuerst, dass ich dynamisch zwischen Master und dem jeweiligen Worker-Thread eine "Shared-Memory-Verbindung" herstelle.

1.)
Ist dies eine gute Vorgehensweise?
Gibt es noch eine andere Möglichkeit außer QtSharedMemory ?

2.)
Was noch in Frage kommen würde ist :
ich reserviere irgendwo Speicher, welchen ich mit z.B. Mutex schütze.

Wo sollte ich diesen Speicher reservieren?
Und wie sollten die Threads darauf zugreifen?

Evtl. da wo meine Thread-Instanzen erzeugt wurden? (im Parent)
So dass die threads über den this Ptr (vom Parent) auf den gem. Speicher zugreifen.

3.)
bezieht sich auf Frage 2)
Was ist wenn der Speicher nicht im Parent sondern ganz woanders liegen sollte.
Wäre ja unschön über mehrere Objekte den Pointer weiterzureichen.
Das kann man sicherlich noch besser realisieren.


Wie würdet ihr sowas realisieren?
Manchmal ist man gezwungen an Daten, die in anderen Instanzen liegen ranzukommen.
Hierbei kommt es vor, dass viele Objekte nicht auf der gleichen Ebene liegen sondern verschachtelt in anderen Objekten liegen.



Gruß

diddely

Verfasst: 27. September 2008 18:44
von diddely
Eine andere Frage, die ich mir gerade stelle bezieht sich auf das Master-Worker-Modell.

Ist es sinnvoll, die Worker-Threads im Master-Thread zu erzeugen?

Ich meine irgendwo im Forum gelesen zu haben, dass diese Vorgehensweise nicht zu empfehlen ist. Leider finde ich diesen Beitrag nicht mehr.

Verfasst: 27. September 2008 19:54
von Christian81
Threads brauchen kein QtSharedMemory - Threads teilen sich den gleichen Speicher.

Verfasst: 27. September 2008 21:04
von upsala
Ist es sinnvoll, die Worker-Threads im Master-Thread zu erzeugen?
Wo willst du ansonsten deine Threads erzeugen?

Verfasst: 27. September 2008 21:06
von diddely
habe mehrere Thread-Instanzen,..

die dürften sich gegenseitig nicht stören.

Verfasst: 27. September 2008 21:09
von diddely
upsala hat geschrieben:
Ist es sinnvoll, die Worker-Threads im Master-Thread zu erzeugen?
Wo willst du ansonsten deine Threads erzeugen?
Eigentlich schon sooo aber...
Wie gesagt, habe hier im Forum irgendwo gelesen, dass man sowas nicht machen soll. Finde den Beitrag gerade nicht.
Suche mal gerade...

Verfasst: 27. September 2008 21:11
von diddely
Meine Aussage bezieht sich auf diesen Beitrag:
http://qtforum.de/forum/viewtopic.php?t ... ht=qthread
Imho ist es ein Designfehler wenn ein Thread einen weiteren erzeugt.

Verfasst: 27. September 2008 22:45
von Christian81
Damit meinte ich aber nur dass in einem QThread nicht unbedingt weitere QThreads erzeugt werden sollten. Da kommt man sonst nicht mehr raus. Mehr nicht.

Verfasst: 28. September 2008 01:14
von diddely
stehe gerade auf dem Schlauch. :?:
Also ist es nicht empfehlenswert worker-threads im Master zu erzeugen?

Verfasst: 28. September 2008 09:30
von Volker
Mit Master Thread meint Christian denke ich den GUI Thread der Anwendung, der auf jeden Fall immer erzeugt wird. Und seine Aussage bezog sich auf neu erzeugte Threads die aus diesem Thread erzeugt wurden.

Verfasst: 28. September 2008 17:38
von diddely
Ok,

meine Aussage bezieht sich nicht auf die GUI.
Wirklich nur das "Master-Worker-Modell".

Master, der die Arbeiten verteilt...die Arbeiter,..die die Arbeit verrichten.
Gut...ich werde die Worker dann im Master(Verteiler)-Thread erzeugen.

Wie soll ich am besten die Daten vom Master an die Worker übergeben?
Mir fällt auf die schnelle ein einfacher Funktionsaufruf ein:

Sowas hier:

Worker.getWork(data);

Der Master ruft die Method vom Worker auf um die Daten rüberzuschieben.
Oder gibt es da eine elegantere Vorgehensweise?
(Worker und Master sind unterschiedliche Klassen)

Verfasst: 29. September 2008 08:34
von solarix
Oder gibt es da eine elegantere Vorgehensweise?
Signal/Slot?

Verfasst: 29. September 2008 08:35
von Christian81
Funktionsaufruf oder ein Pointer. Der Funktionsaufruf ist imho besser da man ihn besser vor konkurrierenden Zugriff schützen kann (d.h. man kann es nicht irgendwo durch Zufall vergessen).

/edit: Signal-Slot ist auch eine Idee - aber eben Qt-spezifisch und Threadübergreifend erst seit Qt4 :)

Verfasst: 29. September 2008 12:54
von diddely
Ok danke!

Um es nochmal zu wiederholen:
Der Master-Thread würde die zu verteilenden Daten abholen, dann würde es sich den richtigen Thread aussuchen und mit einem worker.get_work(data) die Daten übergeben. (Oder wie empfohlen mit Signal/Slot)

Bei Signal/Slot müsste ich aber für jeden worker einen individuelles signal haben. worker0 kann nicht Daten bekommen, die für worker1 gedacht sind usw..
Von daher finde ich , dass es mit Funktionsaufrufen besser zu lösen ist.


Nochmal eine Überlegung zum Master-Thread:

Am besten stelle ich es mal so dar:
Objekt A = Parent
Obejkt B = Serial Objekt (sammelt Daten vom COM-Port)
Objekt C = Master(Verteiler)-Thread-Instanz

Objekt B und C werden im Parent A erzeugt.

Wenn mein Serial-Objekt B seine Daten gesammelt hat, schickt es ein Signal an Master-Thread.
Der muss nun die Daten von Objekt B abholen.
Hierfür habe ich den ptr von Objekt B über den Parent an Master-Thread weitergereicht, damit dieser an die gesammelten Daten von Objekt B rankommen kann.

Ich persönlich finde diese ptr-Weiterreichung unschön.
Ich denke mal ihr stimmt mir das zu????

Eine Möglichkeit wäre die Daten per Signal/Slot weiterzureichen.
Die Daten, die ich weiterreichen will sind eine Liste mit QbyteArrays.

Code: Alles auswählen

QList<QByteArray>

Verfasst: 29. September 2008 15:57
von Superheftig
Der einfachste Weg ist ne eigene Klasse zu erstellen, die die Daten verwalten. Diese Klasse machste als Singleton, dann kannste von überall drauf zugreifen. Innhalb der Klasse speicherste die daten private und machste ne get und set Methode die du per Mutex schützt. Fetig...Thread Save und du kommst von überall im Code dran.
Sieht dann so aus.

Class DataClass {

// Das ist der Singleton Teil der Klasse
public:
static Singleton * instance() // Pointer auf das Singleton Objekt
{
if( _instance == 0 ) _instance = new Singleton();
return _instance;
}
private:
Singleton() { /* ... */ } // Privater Konstruktor
static Singleton *_instance; // Das Singleton Objelt

// Der Teil ist für die Daten
public:
enqueue(DataType &newData) { // Neue Daten einfügen
MutexLocker locker(&mutex);
dataQueue.enqueu(newData);
}

DataType dequeue() { // Daten abarbeiten
MutexLocker locker(&mutex);
return dataQueue.dequeue();
}


private:
QQueuet<DataType> dataQueue;
QMutex mutex;

};

Wenn du die Daten jetzt von irgendwo im Code benutzten willst musst du nur die Klasse includen und dann DataClass::instance()->enqueue() bzw dequeue() aufrufen.
Ach und nicht das löschen des Singleton vergessen. Ganz am Ende wenn dein Programm terminiert einmal delete DataClass::instance() aufrufen.