Seite 1 von 1
Frage zu QThread::currentThread()
Verfasst: 3. August 2010 12:09
von Willi2793
Ich habe ein Verständnisproblem in Bezug auf die genannte Funktion "currentThread()". Ich habe einen Thread in dem ich eine Datenbankverbindung aufbaue. Um die Connection per Thread neu aufbauen zu können habe ich eine Verwaltungsklasse dazu geschrieben die auf "currentThread()" basiert. Dazu baue ich mir auf folgende Weise den connectionName zusammen:
"SQL"+QByteArray((const char*)QThread::currentThread(),4).toHex().toUpper()
Das funktioniert soweit auch ganz gut. Nun erstelle ich mir für jede der Datenbanken einen neuen (anderen) Thread in dem ich in dessen "run()"-Funktion mir wieder eine Connection aufbaue. Ich habe nun erwartet das mir hier in den verschiedenen run-Funktionen die Funktion "QThread::currentThread()" verscheidene Werte gibt. Aber sie gibt mir immer denselben Wert.
Habe ich da einen Denkfehler?
Danke und Grüße,
Willi
Verfasst: 3. August 2010 12:36
von Christian81
Dann wird die Funktion wohl nicht im Context des erzeugten Threads aufgerufen. Oder der Thread wird gar nicht gestartet oder was auch immer.
Verfasst: 3. August 2010 14:32
von pfid
Folgende Fragen fallen mir ein:
- wieso castest du einen QThread* auf const char*?
- was soll im ByteArray drin stehen?
- falls die Adresse des QThread-Objekts drinstehen soll, was machst du dann auf ner 64Bit Plattform?
- willst du vielleicht QThread::currentThreadId()?
Okay ich gebs zu, ich versteh deinen Code nicht

Verfasst: 3. August 2010 15:14
von Willi2793
Christian81 hat geschrieben:Dann wird die Funktion wohl nicht im Context des erzeugten Threads aufgerufen. Oder der Thread wird gar nicht gestartet oder was auch immer.
Daran dachte ich auch schon. Ich mache das (verkürzt) jetzt so:
In Klasse A:
Code: Alles auswählen
for (int i = 0 ; i < n ; i++) {
b* = new B();
connect(b, started(), b, func());
b->start();
}
In Klasse B:
Code: Alles auswählen
void B::run() {
exec();
}
void B::func() {
qDebug() << QThread::currentThread();
}
Natürlich mache ich auch entsprechende deleteLater() usw. Aber der qDebug() gibt mir für alle Bs denselben Wert. Nach meinem Verst#ndnis müßte der immer ein anderer sein?
pfid hat geschrieben:Folgende Fragen fallen mir ein:
- wieso castest du einen QThread* auf const char*?
- was soll im ByteArray drin stehen?
- falls die Adresse des QThread-Objekts drinstehen soll, was machst du dann auf ner 64Bit Plattform?
- willst du vielleicht QThread::currentThreadId()?
Okay ich gebs zu, ich versteh deinen Code nicht

Ich versuche es zu erklären:
- Weil QByteArray im Konstruktor hier "const char *" haben will.
- Danach soll der QThread* im QByteArray stehen den ich dann erst in Hex umwandel und danach in Großbuchstaben damit es lesbar ist und keine Sonderzeichen enthält.
- Das ist ein Argument dem ich mich nicht verschliessen kann. Das kann ich aber natürlich anpassen

- das habe ich versucht, ändert aber leider nichts daran das auch das nicht unterschiedlich ist.
Verfasst: 3. August 2010 15:24
von pfid
Willi2793 hat geschrieben:
- Danach soll der QThread* im QByteArray stehen den ich dann erst in Hex umwandel und danach in Großbuchstaben damit es lesbar ist und keine Sonderzeichen enthält.
Also quasi, die ersten 4 Bytes des QThread Objekts in Hex, ja? (Wozu ist das gut?)
Klasse B erbt von QThread, und im connect-Aufruf hast du auch noch die Signal & Slot Markos drumrumgebastelt, ja?
Kann mir gerade nicht vorstellen, dass dir in dem Slot unterschiedliche Thread-IDs ausgegeben werden. Bist du unter Unix oder Windows unterwegs? Könntest du das qDebug() im Slot mal um pthread_self() (Unix) sowie this erweitern? Oder noch besser, die Ausgabe in die :run() Methode packen? Eventuell wird dir der Slot im falschen Context ausgeführt.
Verfasst: 3. August 2010 15:31
von Willi2793
pfid hat geschrieben:Also quasi, die ersten 4 Bytes des QThread Objekts in Hex, ja? (Wozu ist das gut?)
Nein, nicht die ersten 4 Byte sondern die Adresse selber. currentThread() gibt doch die Adresse zurück.
pfid hat geschrieben:Klasse B erbt von QThread, und im connect-Aufruf hast du auch noch die Signal & Slot Markos drumrumgebastelt, ja?
Kann mir gerade nicht vorstellen, dass dir in dem Slot unterschiedliche Thread-IDs ausgegeben werden. Bist du unter Unix oder Windows unterwegs? Könntest du das qDebug() im Slot mal um pthread_self() (Unix) sowie this erweitern?
Klar habe ich SIGNAL und SLOT drum gebastelt. Das habe ich jetzt in der Kurzform vergessen.
Aber jeder der Bs ist doch ein eigener Thread und der sollte doch auch eigene Adressen bzw. Ids haben, oder?
pthread_self() sagt mir jetzt nix. Und this ist schlecht möglich da currecntThread() eine statische Funktion ist.
Ich bin im Moment unter Windows unterwegs.
Verfasst: 3. August 2010 15:38
von franzf
Willi2793 hat geschrieben:Ich mache das (verkürzt) jetzt so:
[...]
Du vermixt die beiden Vorgehensweisen bei QThread:
ABleiten, und dafür was sinnvolles in die run(). exec() steht per Default drinnen, deshalb macht das Ableiten keinen Sinn so.
Den Worker von QObject ableiten, und per obj->moveToThread(newThread) das Abarbeiten der Events in den Thread verschieben. Das moveToThread wäre das was dir noch fehlt, lies dir aber auch nochmal
diesen Thread durch, da steht viel dazu.
Verfasst: 3. August 2010 16:12
von pfid
Willi2793 hat geschrieben:pfid hat geschrieben:Also quasi, die ersten 4 Bytes des QThread Objekts in Hex, ja? (Wozu ist das gut?)
Nein, nicht die ersten 4 Byte sondern die Adresse selber. currentThread() gibt doch die Adresse zurück.
Ja, aber nachdem du das in das QByteArray verfrachtet hast, nicht mehr. Da stehen dann, wie schon gesagt, die ersten 4 Bytes aus dem Speicherbereich auf den der Pointer zeigt.
Willi2793 hat geschrieben:
pthread_self() sagt mir jetzt nix. Und this ist schlecht möglich da currecntThread() eine statische Funktion ist.
Ich bin im Moment unter Windows unterwegs.
Okay unter Windows wirds mit pthread_self() nicht klappen. Wenn du qDebug() << this; in der run()-Methode von B hinschreibst, sollte er dir den this-Pointer ausgeben

Damit wollte ich nachschauen, welche B-Instanz mit welcher Thread-Id in der run-Methode rumgurkt. Da würde man dann vermutlich sehen, dass alles korrekt ist. Die gleiche Debug-Meldung im Slot würde dir vermutlich aber eine andere Thread-Id mit gleichem this-Pointer ausgeben. Sprich: Slot wird im falschen Context ausgeführt.
Verfasst: 3. August 2010 19:00
von Willi2793
franzf hat geschrieben:Du vermixt die beiden Vorgehensweisen bei QThread:
ABleiten, und dafür was sinnvolles in die run(). exec() steht per Default drinnen, deshalb macht das Ableiten keinen Sinn so.
Den Worker von QObject ableiten, und per obj->moveToThread(newThread) das Abarbeiten der Events in den Thread verschieben. Das moveToThread wäre das was dir noch fehlt, lies dir aber auch nochmal
diesen Thread durch, da steht viel dazu.
Danke, das war extrem hilfreich. In dem Thread und dem dort verlinkten Blog steht wirklich viel hilfreiches.
pfid hat geschrieben:Ja, aber nachdem du das in das QByteArray verfrachtet hast, nicht mehr. Da stehen dann, wie schon gesagt, die ersten 4 Bytes aus dem Speicherbereich auf den der Pointer zeigt.
Oh, das war peinlich von mir. Klar, jetzt ist es mir auch wie Schuppen aus den Haaren gefallen. Danke.
pfid hat geschrieben:Okay unter Windows wirds mit pthread_self() nicht klappen. Wenn du qDebug() << this; in der run()-Methode von B hinschreibst, sollte er dir den this-Pointer ausgeben

Damit wollte ich nachschauen, welche B-Instanz mit welcher Thread-Id in der run-Methode rumgurkt. Da würde man dann vermutlich sehen, dass alles korrekt ist. Die gleiche Debug-Meldung im Slot würde dir vermutlich aber eine andere Thread-Id mit gleichem this-Pointer ausgeben. Sprich: Slot wird im falschen Context ausgeführt.
Ach so, den this-Pointe selber ausgeben. Jetzt habe ich es verstanden

Aber das grundsätzliche Problem wurde durch den oben zitierten Beitrag gelöst.
Eine Frage habe ich jetzt aber noch. Wenn man sich ein Kennzeichen basteln will das den Thread eindeutig identifiziert, ist es dann "besser" currentThread() oder currentThreadId() zu verwenden? Oder ist das als gleichwertig anzusehen?