[gelöst] QThread startet QThreads blockweise
[gelöst] QThread startet QThreads blockweise
Hallo,
ich bin erst vor Kurzem von einem anderen Framework (wxWidgets) auf Qt umgestiegen. Unter Qt komme ich irgendwie mit komplexeren Thread Sachen nicht mehr klar.
Ich versuche folgendes zu realisieren (unter wx hab ich eine Lösung, die sich leider nicht 1:1 umsetzen lässt).
Folgendes: ich habe einen Workerthread (QThread) und der soll 100 CalcThreads (QThread) starten, jedoch so, das immer nur 5 gleichzeitig aktiv sind. Und immer wenn einer fertig wird, wird ein neuer gestartet, bis alle 100 abgearbeitet sind.
Kann mir mal jemand mit Pseudocode oder gleich Qt Code schreiben, wie ich da am Besten vor gehe und worauf ich achten muss?
Wollte das so machen, das ich in einem Array / Vector immer die 5 aktiven Threads verwalte und die sich dann beim Signal "finished()" automatisch aus dem Array austragen, so das der Platz neu befüllt werden kann.
Irgendwie klappt das vorn und hinten nicht. Vielleicht hab ich auch nur ne Denkblockade.
Deswegen ist jeder Hinweis willkommen.
Danke!
ich bin erst vor Kurzem von einem anderen Framework (wxWidgets) auf Qt umgestiegen. Unter Qt komme ich irgendwie mit komplexeren Thread Sachen nicht mehr klar.
Ich versuche folgendes zu realisieren (unter wx hab ich eine Lösung, die sich leider nicht 1:1 umsetzen lässt).
Folgendes: ich habe einen Workerthread (QThread) und der soll 100 CalcThreads (QThread) starten, jedoch so, das immer nur 5 gleichzeitig aktiv sind. Und immer wenn einer fertig wird, wird ein neuer gestartet, bis alle 100 abgearbeitet sind.
Kann mir mal jemand mit Pseudocode oder gleich Qt Code schreiben, wie ich da am Besten vor gehe und worauf ich achten muss?
Wollte das so machen, das ich in einem Array / Vector immer die 5 aktiven Threads verwalte und die sich dann beim Signal "finished()" automatisch aus dem Array austragen, so das der Platz neu befüllt werden kann.
Irgendwie klappt das vorn und hinten nicht. Vielleicht hab ich auch nur ne Denkblockade.
Deswegen ist jeder Hinweis willkommen.
Danke!
Zuletzt geändert von wobaa666 am 2. Februar 2008 20:40, insgesamt 1-mal geändert.
-
PeterLustig
- Beiträge: 386
- Registriert: 21. November 2007 20:07
-
Christian81
- Beiträge: 7319
- Registriert: 26. August 2004 14:11
- Wohnort: Bremen
- Kontaktdaten:
Hier mal meine erste Herangehensweise:
Dadurch, das ich in der Worker::run() ein while mache, komm ich anscheinend nie in den Genuss auch mal ein finished() signal zu erhalten. Damit startet er mir 5 Threads und dann ists ne Endlosschleife.
In der Doku steht, das ich im Worker ein exec() einbauen müsste, damit ich in den EventLoop starte. Ich habe aber keine Ahnung an welcher Stelle das sein sollte.
wäre ein Timer vielleicht die Lösung für das ungeschickte while?
Code: Alles auswählen
int numThreads = 0;
int numCalc = 100;
void Worker:run() {
while(numThreads < 5 && numCalc > 0) {
CalcThread* calc = new CalcThread();
connect(calc, SIGNAL(finished()), this, SLOT(OnCalcFinished());
calc->start();
numThreads++;
numCalc--;
}
while(numThreads > 0) {
qDebug() << "es laufen noch threads";
}
}
void Worker::OnCalcFinished() {
numThreads--;
}
Dadurch, das ich in der Worker::run() ein while mache, komm ich anscheinend nie in den Genuss auch mal ein finished() signal zu erhalten. Damit startet er mir 5 Threads und dann ists ne Endlosschleife.
In der Doku steht, das ich im Worker ein exec() einbauen müsste, damit ich in den EventLoop starte. Ich habe aber keine Ahnung an welcher Stelle das sein sollte.
wäre ein Timer vielleicht die Lösung für das ungeschickte while?
-
Christian81
- Beiträge: 7319
- Registriert: 26. August 2004 14:11
- Wohnort: Bremen
- Kontaktdaten:
ja, das ist mir klar. durch meine Endlosschleife verlässt er ja nie das run. Ist ja aber auch kein Problem nen Thread als Membervariable zu deklarieren. Aus :run() möchte ich ja auch erst raus, wenn 100x der CalcThread aufgerufen wurde und diese fertig sind.Christian81 hat geschrieben:Sobald du ::run() verlässt sind deine Threads weg.
Ich bekomme leider kein finished() Signal an den Worker zurück. Hab das Ganze jetzt mal nur mit einem Thread versucht, aber da bekomm ich auch kein Signal gesendet.
Code: Alles auswählen
CalcThread calc;
void Worker:run() {
connect(&calc, SIGNAL(finished()), this, SLOT(OnCalcFinished());
calc->start();
exec();
}
void Worker::OnCalcFinished() {
qDebug() << "Thread finished()";
}
-
Christian81
- Beiträge: 7319
- Registriert: 26. August 2004 14:11
- Wohnort: Bremen
- Kontaktdaten:
In der Doku steht zu QThread::exec(): "It is necessary to call this function to start event handling. "Christian81 hat geschrieben:Da Du nicht in der Eventloop bist, kann der Thread auch kein Signal bekommen.
Schön und gut, aber wo und wann? im letzten Code, den ich gepostet habe, ist das exec() drin, dennoch kommt kein Signal.
Wenn Du mir verraten könntest, wie ich den Worker Thread zu einem EventLoop überreden kann, würde mir das sicher viele graue Haare sparen.
Wenn die Signale ankommen, sollte es auch kein Problem sein, die mehrere Threads zu clustern.
-
Christian81
- Beiträge: 7319
- Registriert: 26. August 2004 14:11
- Wohnort: Bremen
- Kontaktdaten:
Also mein CalcThread sieht in etwa so aus:
Das "CalcThread::run()" wird auch ausgegeben
Hab in dem Thread auch schon mit exec() rum gespielt, immer ohne Erfolg.
Qt meldet auch keinen Hinweis, dass das connect gescheitert ist.
Viele Grüße, Jan
Code: Alles auswählen
class CalcThread : public QThread
{
public:
void run();
};
void CalcThread::run()
{
qDebug() << "CalcThread::run()";
}Hab in dem Thread auch schon mit exec() rum gespielt, immer ohne Erfolg.
Qt meldet auch keinen Hinweis, dass das connect gescheitert ist.
Viele Grüße, Jan
-
Christian81
- Beiträge: 7319
- Registriert: 26. August 2004 14:11
- Wohnort: Bremen
- Kontaktdaten:
-
Christian81
- Beiträge: 7319
- Registriert: 26. August 2004 14:11
- Wohnort: Bremen
- Kontaktdaten:
Ich habe ein sleep(10) in den CalcThread:run() eingebaut. Danach dann die Ausgabe.
Hab mit'm Debugger geprüft, ob er auch vorher in das Exec() von Worker rein geht. Das passt. Nach ner ganzen Weile kommt dann halt die Ausgabe auf der Konsole, aber trotzdem kommt kein Signal.
Kann das irgend etwas mit dem Q_OBJECT in der Klassendefinition zu tun haben?
Ich habe es momentan bei beiden Threads drin. Sowohl Worker als auch Calc.
Hab mit'm Debugger geprüft, ob er auch vorher in das Exec() von Worker rein geht. Das passt. Nach ner ganzen Weile kommt dann halt die Ausgabe auf der Konsole, aber trotzdem kommt kein Signal.
Kann das irgend etwas mit dem Q_OBJECT in der Klassendefinition zu tun haben?
Ich habe es momentan bei beiden Threads drin. Sowohl Worker als auch Calc.