QThread Speicherzugriffsfehler

Alles rund um die Programmierung mit Qt
Antworten
samy75
Beiträge: 3
Registriert: 27. August 2009 11:52

QThread Speicherzugriffsfehler

Beitrag von samy75 »

Hallo zusammen,

ich kämpfe momentan mit einem Problem, das ich nicht mehr so richtig verstehe. Ich habe ein Programm, welches 4 Threads startet und die Thread kommunizieren untereinander über eine separate Klasse als geteilter Speicher.
Wenn ich jetzt nun einen ADVector ( vector < B < F <interval> > > ) aus dem Speicher abrufen will, so produziert mir das Programme ab und zu einen Speicherzugriffsfehler. Wenn ich die Zeile mit dem Zugriff auskommentiere, so bleibt der Fehler aus, genauso, wenn ich statisch einen ADVector weiter übergebe.

Sobald ich die Thread ein wenig mit this->msleep(...) ausbremse, so läuft das Programm stabil, genauso wenn ich Debug Symbole hinzufüge (im .pro CONFIG += debug), läuft das Programm auf Grund des verlangsamten Ablaufs stabil.

Da es sich um ein Optimierungsprogramm handelt, sollte es so schnell wie möglich die Daten bearbeiten und nicht ausgebremst werden. Hier der Code-Schnipsel dazu :

Code: Alles auswählen

//////////////////////////////////////////////////
// Mutex - Datenaustausch
/////////////////////////////////////////////////

  if (dataMutex.tryLock())
  {
    if(!liste->empty()) { // Liste ist eine stl_map
      // Pruefen, ob neue Datensaetze benoetigt werden
      if(liste->size() > 1) {
	if(dataStorage->needData())
	{
	  dataStorage->sendADVector(liste->begin()->second, threadID);
	  liste->erase(liste->begin());
	}
     }
     dataMutex.unlock(); 
    }
    // Liste ist leer, Daten anfordern
    else {
      if(!registeredEmptyList) {
	dataStorage->ranOutOfData(threadID); 
	registeredEmptyList = true;
      }
      // neue Datensaetze beschaffen und diesen abspeichern
      if(dataStorage->hasNewADVectorForThread(threadID)) {
	setInitialADVector(dataStorage->getADVector(threadID));
	initializeListe();
      }
      
      if(dataStorage->allThreadsIdle())
	finished = true;
      dataMutex.unlock(); 
      this->msleep(12);
    }
  }
(dataMutex ist ein static Member der Klasse). Das dataMutex.unlock() ist absichtlich in die if bzw. else Codeblocks eingefuegt, um ein sleep() nur für die aufzurufen, die keine Daten haben.

Für jede Hilfe wäre ich echt dankbar. Übrigens hab ich auch schon den boost vector verstucht!

samy75
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

Ausser dass der Code schlecht formatiert und kaum lesbar ist, sieht man nicht wirklich was dort gemacht wird.

Du hast 4 Threads, und eine Klasse X die Daten hält, so weit richtig?

Die gezeigte Methode soll nun Daten aus dieser Klasse lesen, oder welche dort ablegen. Das machst du indem du in der Methode ein Element aus der lokalen Liste des Threads nimmst und in Klasse X schiebst, oder umkgekehrt. Richtig?

Dazu 2 Fragen:

1) greifst du an anderen Stellen auf die Daten zu?
2) speicherst du dir Pointer oder kopierst du Objekte?
samy75
Beiträge: 3
Registriert: 27. August 2009 11:52

Beitrag von samy75 »

Das ist soweit alles richtig,

zu 1.)
ich greife auf das Objekt dataStorage, welches die Daten enthält nur in diesem Bereich (Mutex) zu.

zu 2.)
Ich übergebe const reference Objekte

zu Formatierung.)
Soll ich es für das Forum anders formatieren ? Im Editor (Kate) formatiert er mir auch die Tabs und ist dort gut lesbar
samy75
Beiträge: 3
Registriert: 27. August 2009 11:52

Beitrag von samy75 »

Habe den Fehler gefunden :
Im Datentyp ADVector war der Copy Contructor nicht Thread sicher! (War aus dem Datentyp der FADBAD++ zusammengesetzt :

typedef vector< B < F < interval > > > ADVector;

)

und eben die B bzw. F Datentypen haben das Problem verursacht.

Dennoch danke für die Hilfe
Antworten