Seite 1 von 1

Threads handeln

Verfasst: 2. Dezember 2005 19:09
von ddaannyy
Hallo,

um threads besser zu verstehen habe ich folgendes Szenario:

eine Basisklasse und davon 2 Threads. In der Basisklasse habe ich eine Variable, die ich per Adressübergabe an beide Threads weitergebe. Thread A erhöht die Variable um +1 Thread B -1. Starte und stoppe ich jeden Thread einzeln, dann ist alles ok, zusammen geht nicht.

Code: Alles auswählen

void Thread_A::run()
{
	QMutex mutex;
	for (;;)
	{
		mutex.lock();
		if (stopped)
		{
			stopped=false;
			mutex.unlock();
			break;
		}
		(*z)++;
    		if ( (*z)>10000000 ) (*z) = 0;
        	cerr << *z << "  *  "  << z << "    A\n";
		mutex.unlock();
	}	
}

Fragen:

1. Mir ist klar, das sie beide auf dem selben Speicher laufen, aber kann man den Thread oder den Teil des Speichers nicht gegen Mehrfachnutzung schützen, so das es da zu keinen Problemen kommt.

2. Der Idealfall wäre, wenn die Variable um 0 pendelt. Das bringt mich gleich zur nächsten Frage. Kann ich die Priörität von einem Thread erhöhen? Dann müßte sie langsam in eine Richtung laufen.

3. Welche Funktion kann ich in der Basisklasse nutzen um auch standig eine Anzeige auf der Konsole zu bekommen. Meine Basisklasse ist vom Typ QDialog. Mit run() habe ich da keinen Erfolg.

Code: Alles auswählen

cerr << *z << "  *  "  << z << "    B\n";

Verfasst: 23. Dezember 2005 11:48
von kowi1134
Hallo!

Ich bin kein Experte was Threads angeht, aber ich glaube ich habe in der Theorie verstanden, wie man einen konkurrierenden Zugriff realisiert!

Mir scheint, Du versuchst in Deiner Thread_A::run()-Methode, einen Block mit einem Mutex absichern zu wollen. Das ist aber Käse, denn wenn Du mal überlegst, dann bringt das gar nichts, um einen atomaren Zugriff auf deine Zählervariable zu realisieren.

Nebenbemerkung:
Es ist bei Blockern wie Mutexen oder Semaphoren wichtig, dass beide Prozesse sie kennen! D.h. Du darfst schon mal nicht in jeder run()-Methode einen neuen Blocker erzeugen. Es ginge, diesen Mutex global zu machen, aber davon rate ich ab. Eine bessere Möglichkeit ist es, Dein Zählervariable threadsicher zu machen, denn dass ist schliesslich der Teil auf den der konkurrierende Zugriff stattfindet!

Versuch mal folgendes:

1.) Nimm aus Deinen run()-Methoden die Mutexe raus, denn die brauchst Du nicht.

2.) Aus Deiner Zählervariable machst Du mal ein Objekt dieser Klasse:

Code: Alles auswählen

class Counter {
public:

  Counter()
  {
   cnt = 0;
  }

  int add(int operand)
  {
    QMutex mutex;
    mutex.lock();
    cnt += operand;
    return cnt;
    mutex.unlock();
  }

private:
  int cnt;
};
3.) Jetzt musst Du nur noch die Stellen im Code ändern an denen Du +1 oder -1 auf deine Zählervariable addierst und sie mit einem Aufruf der Form

Code: Alles auswählen

myCounter->add(-1)
ersetzen. Hierbei ist myCounter natürlich ein Zeiger auf dein Objekt vom Typ Counter. Du kannst ja dann das Ergebnis des add()-Aufrufs auf der Konsole ausgeben (z.B. mit

Code: Alles auswählen

qDebug( QString::number(myCounter->add(-1)) );


Viel Grüße
Konrad