Gescheites Klassendesign für PThread worker
-
Hallo,
Ich möchte folgendes Design realisieren:
Ein Worker Thread (eingebettet bzw. gestartet aus einer Klasse) hört die Serielle Schnittstelle ab und speichert empfangene Wert in einer Map.
Gekürzte Class Definition.static map<string, float> storage; static bool addTostorage(string, float); class PICmirror { public: void stop(void); bool checkForHangingNews(void); bool signalHangingNews(void); float getValue(string); private: static void * startThread(void *); pthread_t pThreadListener; volatile bool newsHanging; volatile bool stopRequest; pthread_mutex_t mutexNewsFlag; pthread_mutex_t mutexStorage;
Meine Hauptproblem ist, dass ich vom Thread nicht auf this zugreifen kann. Stattdessen muss ich der Thread-Funktion den this-Pointer übergeben, diesen casten, um ihn schliesslich zu verwenden. Das sieht etwa so aus:
void *PICmirror::startThread(void * obj) { //All we do, is to call the starting function reinterpret_cast<PICmirror *> (obj)->listenToSerial(obj); return NULL; }
1. Frage: Kennt jemand einen besseren Ansatz, um einen pThread elegant in eine Klasse einzubauen? Gibt es gar eine Möglichkeit im Thread direkt auf this zuzugreifen?
Schliesslich möchte ich die gewonnen Daten den restlichen Klassen in einer Map zur Verfügung stellen. Hier kann ich entweder die Map als statische Variable definieren, um ohne grosse Umstände auf die Map vom Thread her zuzugreifen oder ich lagere den Datenspeicher in eine externe Klasse aus. (Dann habe ich jedoch wieder Schwierigkeiten mit den Mutex.)
2. Frage: Wie schlimm ist es, über die Thread-Klassen den anderen Klassen Zugriff auf die statische Map zu gewähren?
Eure Meinung bzw. Erfahrung würde mich interessieren.
-
"Stattdessen muss ich der Thread-Funktion den this-Pointer übergeben, diesen casten, um ihn schliesslich zu verwenden. Das sieht etwa so aus ..."
Das ist der vorgesehene Weg und ich habe das genau so schon oft gemacht.
Einziges Problem das du lösen musst: Du musst sicher stellen das die Klasse worauf der this Pointer zeigt nicht gelöscht wird solange wie der Thread läuft.
Das sollte im Destruktor der Klasse geprüft und sicher gestellt werden.Statische Variablen und Threads passen nicht gut zusammen und können eine
ganze Menge Ärger machen. Wenn möglich verzichte einfach darauf.
Falls du diese Kombination dennoch verwenden möchtest musst du den Zugriff
über eine zusätzliche statische CriticalSection (Mutex) absichern.Also: die Sache mit dem this Pointer ist der richtige Weg ...
Zusätzlich werden bei mir in diesem Fall ALLE Zugriffe auf die Klassen
Member über Getter und Setter realisiert.
In den Gettern und Settern verwende ich sogenannte LockGuards
(Scoped Mutexe, kleine Helper Klassen, die automatisch im Construktor Lock und im Destruktor Unlock ausführen).Viel Erfolg, Gruß Frank.