Pro Worker-Thread eine GUI-Thread?

Alles rund um die Programmierung mit Qt
diddely
Beiträge: 49
Registriert: 9. Juli 2008 16:19

Beitrag von diddely »

Ist die allgemeine Vorgehensweise im oberen Beispiel ok?

Nun zu dem Beitrag von RHBaum:

In der obigen Beschreibung von RHBaum wurde eine Thread(1)-Instanz erzeugt und wenn ich es richtig verstanden habe wurde innerhalb dieser Instanz ein weiterer Thread(2) erzeugt, der sofort pausiert wurde.

Thread(2) stellt eine Einsprungsfunktion bereit an die wir aus Thread(1) den this-Pointer übergeben.

In Thread(2) wird dieser Pointer auf QThread gecastet.

In Thread(1) kann ich mit exec Thread(2) laufens lassen.

in der statischen startmethode wird nix anderes gemacht, als der context zeiger auf QTread gecastet, und an diesem zeiger gleich die methode run aufgerufen
Wer ruft hier run von wo auf?
Beide Threads bieten eine RUN-Methode.

Und weiter gehts...

Thread(2) kennt alle Objekte, die Thread(1) auch kennt (wegen this-pointer)

Falls ich was falsch verstanden habe bitte bescheid sagen.

Last but not least...
unter QT wuerde man das eher anders loesen ... eine Klasse, die mehrere Ableitungen von von qthread instanzieiert (statisch oder dynamisch) , und diese bekommen nen zeiger auf die Instanz in der sie erzeugt wurden.
so koennen dann memberfunktionen von der klasse aus meheren threads aus aufgerufen werden ...
Im Prinzip so wie ich es oben gemacht habe, nur noch einen Pointer übergeben.

Nun bezogen auf meine Aufgabe:
Meiner Meinung nach wäre bei meinen Threads ein Pointer auf die Instanz, wo sie erzeugt werden, uninteressant.
Wüsste jetzt nicht warum ich die Methoden der erzeugenden Klasse von meinem Thread aus aufrufen sollte.

Ich würde so vorgehen:
Die Daten die für das ThreadX angekommen sind übergebe ich als Parameter(z.B. über eine Thread-Funktion), so dass sie in die Thread-Instanz lokal reinkopiert/verarbeitet werden.
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

In der obigen Beschreibung von RHBaum wurde eine Thread(1)-Instanz erzeugt und wenn ich es richtig verstanden habe wurde innerhalb dieser Instanz ein weiterer Thread(2) erzeugt, der sofort pausiert wurde.
Noe !

Du hasst ein QThread Instanz erstellt, das hat noch nix mit nem Thread zu tun. Innerhalb dieser Instanz wird erst der Thread erstellt.
Also pro QThread Instanz hasst du genau einen zusaetzlichen Thread.
Fuers verstaendniss (von der API / C Seite her) musst du Instanzen und Threads trennen.

Siehst du es aber von der Objectorientierten seite, entspricht ein QThread nateuerlich genau nem thread, was da intern vor sich geht, intressiert dich ja ned (black box prinzip).

Dein Beispiel, das kannst natuerlich so machen .....
Aber:

Code: Alles auswählen

 if(threadA.isRunning()){
      threadA.stop();
      m_starta->setText("Start A");
   }else{
      threadA.start();
      m_starta->setText("Stop A");
   } 
Du rufst (new und delete soweiso) start und stop und setmsg auf ? welcher thread ? richtig, ueber die Signal /Slots = GUI Thread ....

in deinem thread:

Code: Alles auswählen

void Thread::run()
{
   int i=0;
   while(!stopped)
      i++;
//      emit sendmsg(message);
   stopped = false;
      
} 
void Thread::stop()
{
   stopped = true;
}

void Thread::setmsg(const QString &msg)
{
   message = msg;
} 
in Run(im Thread von der QThreadInstanz):
while(!stopped) -> auslesen einer bool variable ... nicht atomar !
stopped = false; schreiben einer 32 bit variable

in stop(GUI Thread):
stopped = true; schreiben einer 32 bit variable

definitiv eine race condition !
Das voiatile davor hilft dir da gar nix .... da muss eigentlich Mutex her ....

Code: Alles auswählen

while(!stopped)
      i++; 
Zum testen super, weil toller klassischer Spinlock :-) muesst halt nur ne atomare operation statt der variable nehmen ...

fuer richtige Programme eher ungeeignet, da man sowas besser mit events(im threadcontext) loest. Unter winapi waeren die methoden WaitForSingleObject / WaitForMultiObject .... muss scheuen was die QT dafuer bietet ....

Ciao ...
diddely
Beiträge: 49
Registriert: 9. Juli 2008 16:19

Beitrag von diddely »

Wollte kein neues Topic erstellen, daher schreibe ich hier mal weiter.
Das Problem ist nahezu identisch.


Habe eine Klasse ThreadClass

Code: Alles auswählen

class ThreadClass : public QThread
{

public:
ThreadClass(QObject *parent,bool type);

protected:
void run()

 private:
          int i;

}

Code: Alles auswählen

ThreadClass::run(){
// je nachdem was an den ctor übergeben wurde (bool)
macht der jeweilige Thread i++ oder i-- in einer endlosschleife

true: i++;
false : i--;

//mit qDebug gebe ich die aktuellen Werte aus.
}

mainprogram:

Code: Alles auswählen

erzeuge hier zwei instanzen.

ThreadClass a = new ThreadClass(this,true);
ThreadClass b = new ThreadClass(this,false);

a->start();
b->start();
Jetzt hätte ich erwartet, dass a und b sich gegenseitig stören, also der eine zählt hoch und der andere direkt runter.

Passiert aber nicht, die laufen schön unabhängig voneinander.
Das eine i geht schön ins positive, das andere i ins negative..


Was müsste ich denn tun damit diese beiden Threads auf die selbe Variable i zugreifen müssten?
diddely
Beiträge: 49
Registriert: 9. Juli 2008 16:19

Beitrag von diddely »

Ok mir ist klar, dass es an den zwei Instanzen liegt.
Der Adressraum ist komplett unterschiedlich.

Aber wie mache ich es, wenn ich doch will, dass ein anderes Thread die Variablen mit einem anderen Thread teilen möchte?
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Naja - einfach einen Pointer auf einen gemeinsamen Speicher übergeben würde ich sagen :)
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
diddely
Beiträge: 49
Registriert: 9. Juli 2008 16:19

Beitrag von diddely »

Ok, hätte ja sein können, dass QT was eigenes dafür anbietet.

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

Beitrag von pfid »

RHBaum hat geschrieben:
In der obigen Beschreibung von RHBaum wurde eine Thread(1)-Instanz erzeugt und wenn ich es richtig verstanden habe wurde innerhalb dieser Instanz ein weiterer Thread(2) erzeugt, der sofort pausiert wurde.
while(!stopped) -> auslesen einer bool variable ... nicht atomar !
Sicher? Ich dachte immer int/bool auslesen/setzen wäre atomar..?
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Da auch das schreiben/auslesen eines int's/bool's nicht immer in eine einzige Maschinenanweisung übersetzt werden kann, können solche Anweisung schon aus diesem Grund nicht atomar sein.
Antworten