Shared Memory zwischen Threads
Shared Memory zwischen Threads
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
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
-
Christian81
- Beiträge: 7319
- Registriert: 26. August 2004 14:11
- Wohnort: Bremen
- Kontaktdaten:
Eigentlich schon sooo aber...upsala hat geschrieben:Wo willst du ansonsten deine Threads erzeugen?Ist es sinnvoll, die Worker-Threads im Master-Thread zu erzeugen?
Wie gesagt, habe hier im Forum irgendwo gelesen, dass man sowas nicht machen soll. Finde den Beitrag gerade nicht.
Suche mal gerade...
Meine Aussage bezieht sich auf diesen Beitrag:
http://qtforum.de/forum/viewtopic.php?t ... ht=qthread
http://qtforum.de/forum/viewtopic.php?t ... ht=qthread
Imho ist es ein Designfehler wenn ein Thread einen weiteren erzeugt.
-
Christian81
- Beiträge: 7319
- Registriert: 26. August 2004 14:11
- Wohnort: Bremen
- Kontaktdaten:
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.
Bitte seid so nett und ändert den Titel von Beiträgen die gelöst wurden, auf [gelöst] Beitragstitel
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)
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)
-
Christian81
- Beiträge: 7319
- Registriert: 26. August 2004 14:11
- Wohnort: Bremen
- Kontaktdaten:
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
/edit: Signal-Slot ist auch eine Idee - aber eben Qt-spezifisch und Threadübergreifend erst seit Qt4
MfG Christian
'Funktioniert nicht' ist keine Fehlerbeschreibung
'Funktioniert nicht' ist keine Fehlerbeschreibung
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.
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>-
Superheftig
- Beiträge: 63
- Registriert: 6. September 2008 15:20
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.
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.