[gelöst] Zugriff aus Thread auf Daten vom parent-Objekt

Alles rund um die Programmierung mit Qt
Antworten
mephistho
Beiträge: 58
Registriert: 14. September 2006 17:47

[gelöst] Zugriff aus Thread auf Daten vom parent-Objekt

Beitrag von mephistho »

Hiho,

ich hab einen kleinen TCP-Aufbau basierend auf dem Threaded Fortuneserver aus den QT-Examples.

Dort ruft ja der FortuneServer die FortuneServerThreads auf.

Bei mir hat der Server nun z.B. ein Array aus QStrings "swMatrix". Auf die Inhalte dieses Arrays möchte ich aus den Threads heraus zugreifen.
In dem Array stehen z.B. Ip-Addressen von Geräten, mit denen der Server kommuniziert (ioLogik-Schalter). Und ich möchte nun z.B., dass jeder Client, der sich an dem Server anmeldet eine Liste der verfügbaren IP-Adressen mitgeteilt bekommt.

Wie würdet ihr das realisieren?

Danke und Gruß
meph
Zuletzt geändert von mephistho am 19. September 2007 15:22, insgesamt 3-mal geändert.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Ptr des Haupthreads an die Threads übergeben und fertig.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
mephistho
Beiträge: 58
Registriert: 14. September 2006 17:47

Beitrag von mephistho »

Danke, das dachte ich mir eigentlich auch. Aber ist das nicht schon mit der Übergabe von "this" als parent realisiert?

Code: Alles auswählen

void ioServer::incomingConnection(int socketDescriptor)
{	
	ioServerThread *thread = new ioServerThread(socketDescriptor, this);
	connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));

	thread->start();
}

Code: Alles auswählen

ioServerThread::ioServerThread(int socketDescriptor, QObject *parent) 
	: QThread(parent), socketDescriptor(socketDescriptor)
{
}
So kann ich aber nicht mit parent-> auf meine Daten zugreifen

ioserverthread Zeile 22:

Code: Alles auswählen

text = QString(&parent->swMatrix[0][0] + " <-> " + &parent->swMatrix[0][1]);
Das gibt folgende Fehlermeldung. Egal ob mit & oder ohne...
ioserverthread.cpp:22: error: invalid use of member (did you forget the ‘&’ ?)
ioserverthread.cpp:22: error: base operand of ‘->’ is not a pointer
ioserverthread.cpp:22: error: invalid use of member (did you forget the ‘&’ ?)
ioserverthread.cpp:22: error: base operand of ‘->’ is not a pointer


Oder brauch ich explizit nen Pointer auf den HauptTHREAD, in dem mein ioServer läuft, was dann ja der Hauptthread der ganzen Anwendung wäre?! Wie würd ich da rankommen?

Dank & Gruß
meph
Zuletzt geändert von mephistho am 19. September 2007 09:25, insgesamt 2-mal geändert.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Wenn wir jetzt noch wüssten wo ioserverthread.cpp:22 ist, könnten wir wohl auch helfen.
Ich würde mal sagen dass "&parent" sinnlos ist - ein Ptr auf einen Ptr geht an dieser Stelle recht schlecht... ggf. hast Du da ein paar Klammern vergessen.

Den Parent als QObject * parent zu übergeben ist zwar ok, aber imho (bin mir nicht mehr ganz sicher) gibt es dann ggf. Warnungen/Probleme zur Laufzeit. Der Parent eines QThreads sollte immer 0 sein. Ich finde gerade den Post nicht mehr und es kann auch sein dass ich mich in diesem Punkt irre.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
mephistho
Beiträge: 58
Registriert: 14. September 2006 17:47

Beitrag von mephistho »

Hab den Post oben editiert. Zeile 22 ist die Zeile, in der &parent-> aufgerufen wird...

Die Übergabe als QObject* wirft keine Warnungen aus. Habs so auch aus dem QT-Example übernommen.

Hilfst mir mal kurz auf die Sprünge mit der Syntax zur Pointerübergabe?! Ich hab da in den letzten Tagen so viel ausprobiert, dass ich grad nich mehr weiß, wie ich das normalerweise lösen müsste.

Danke!
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Ich weiss nicht was swparent ist, aber "parent->swMatrix[0][0]" sollte schon gehen wen swMatrix ein Array aus QStrings ist.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
mephistho
Beiträge: 58
Registriert: 14. September 2006 17:47

Beitrag von mephistho »

swparent?

swMatrix ist ein Array aus QStrings, ja. Aber parent->swMatrix[0][0] geht ebenfalls nicht. Gleicher Fehler wie bei &parent->swMatrix[0][0]:
ioserverthread.cpp:22: error: invalid use of member (did you forget the ‘&’ ?)
ioserverthread.cpp:22: error: base operand of ‘->’ is not a pointer
ioserverthread.cpp:22: error: invalid use of member (did you forget the ‘&’ ?)
ioserverthread.cpp:22: error: base operand of ‘->’ is not a pointer
mephistho
Beiträge: 58
Registriert: 14. September 2006 17:47

Beitrag von mephistho »

So, ich denke, ich habs gelöst.

Ich erweitere meine ioServerThread-Klasse um ein

Code: Alles auswählen

private: ioServer *tmpServer;
und übergebe einen Pointer auf ioServer beim Aufruf der Klasse.

Code: Alles auswählen

void ioServer::incomingConnection(int socketDescriptor)
{   
   ioServerThread *thread = new ioServerThread(socketDescriptor, this, this);
   connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));

   thread->start();
} 
Dann kann ich im Konstruktor von ioServerThread den übergebenen Pointer in meinen tmpServer packen und in der Klasse drauf zugreifen.

Code: Alles auswählen

ioServerThread::ioServerThread(int socketDescriptor, ioServer *ios, QObject *parent)
   : QThread(parent), socketDescriptor(socketDescriptor)
{
tmpServer = ios;
} 
Dann aber vielleicht noch was anderes, wofür sich ein eigener Thread vermutlich gar nicht lohnt:

Mein Client, der nun wunderbar Daten übermittelt bekommt, verliert nach 30 Sekunden die Verbindung. Ich weiß grad noch nich, obs am Server liegt, oder am Client.

Fällt euch (dir Christina81) auf die Schnelle ein, ob da in den Tcp-Sachen von Qt irgendwo n Standard-Timeout drinstecken könnte?

Dank & Gruß
meph
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

tcp: nein, nicht das ich wüsste
thread: wenn du von den Daten nur liest ist es so ok. Wenn Du aber auch schreibst, solltest Du eine set() - Funktion machen welche die Schreibzugriffe per QMutex synchronisiert. Sonst kann es crashen
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
mephistho
Beiträge: 58
Registriert: 14. September 2006 17:47

Beitrag von mephistho »

Verdammt, alle 30sek Verbindungsabbruch geht mal gar nich. Und zumindest auf dem Linux-System, auf dem die Serveranwendung läuft, bekomm ich keine Meldung inner Konsole, wie es sonst der Fall ist, wenn was schiefläuft.

Hm, QMutex. Da hab ich noch nie mit gearbeitet.
Evtl. komme ich aber auch ohne aus. Weil eigentlich immer gesichert ist, dass jeder Client immer nur die Daten verändert, die "ihm" gehören - in Abhängigkeit von den IPs.

Obwohl, da bin ich auch auf dem Holzweg, oder? Wenn zwei Clients gleichzeitig auf verschiedene Felder des Arrays zugreifen crasht das genau so, als wenn sie beide auf das selbe Feld zugreifen würden, richtig?
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Es crasht nur wenn genau die gleichen Daten verändert werden.
Wegen dem Verbindungsabbruch - sowas habe ich eigentlich noch nie gehört...
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
mephistho
Beiträge: 58
Registriert: 14. September 2006 17:47

Beitrag von mephistho »

Christian81 hat geschrieben:Es crasht nur wenn genau die gleichen Daten verändert werden.
Das ist fein. Dann sollte das bei mir klappen.


Der Verbindungsabbruch ist mir auch völlig suspekt. Da muss ich mir erst mal was zur Fehlereingrenzung einfallen lassen. Bin für Denkanstöße auf jeden Fall dankbar :?
mephistho
Beiträge: 58
Registriert: 14. September 2006 17:47

Beitrag von mephistho »

Wireshark zeigt mir nach 30 sek den Verbindungsabbau von der Serverseite her an.

[FIN, ACK]-Paket vom Server an den Client. Und dann halt der normale TCP-Verbindungsabbau mit 3-way-handshake oder wie genau das auch immer heißt ;)

:?
mephistho
Beiträge: 58
Registriert: 14. September 2006 17:47

Beitrag von mephistho »

Ganz einfach.
waitForDisconnected hat n Standard-Timeout von? Genau: 30 000 msec

also tcpSocket.waitForDisconnected(-1);

Läuft.
Antworten