QThread und QWaitCondition (gelöst)
Verfasst: 26. August 2010 21:42
Hallo,
ich habe (mal wieder
) eine Frage zum QThread. Diesmal in der Kombination mit einer QWaitCondition.
Ich habe eine Worker-Klasse erstellt und wie in Link beschrieben in den QThread verschoben. In einer doWork()-Methode, die auf der EventLoop des Threads läuft, ist eine while-Schleife implementiert, an deren Ende ein QWaitCondition(&m_pMutex) steht.
Nun wollte ich die Worker-Klasse wieder aufwecken und habe in der Basisklasse ein Signal emittiert, dass eine Funktion in der Worker-Klasse aufruft, die den Thread wieder aufweckt. Diese wird aber im Basisklassen-Kontext ausgeführt und somit erscheint eine Fehlermeldung. Wenn ich diese Funktion einfach aufrufe (wie unten auskommentiert), dann kommt das gleiche. Ebenfalls das gleiche Resultat ergibt sich, wenn ich ein Signal in der Basisklasse emittiere, dass in der Worker-Klasse aufgefangen wird um selber ein Signal zu emittieren, dass auch vion der Worker-Klasse aufgefangen wird um den Thread aufzuwecken.
Wie also wecke ich einen Thread bzw. meine Worker-Klasse auf?
Vielen Dank,
Johannes
Threadtest_6.h
Threadtest_6.cpp
Worker.h
Worker.cpp
ich habe (mal wieder
Ich habe eine Worker-Klasse erstellt und wie in Link beschrieben in den QThread verschoben. In einer doWork()-Methode, die auf der EventLoop des Threads läuft, ist eine while-Schleife implementiert, an deren Ende ein QWaitCondition(&m_pMutex) steht.
Nun wollte ich die Worker-Klasse wieder aufwecken und habe in der Basisklasse ein Signal emittiert, dass eine Funktion in der Worker-Klasse aufruft, die den Thread wieder aufweckt. Diese wird aber im Basisklassen-Kontext ausgeführt und somit erscheint eine Fehlermeldung. Wenn ich diese Funktion einfach aufrufe (wie unten auskommentiert), dann kommt das gleiche. Ebenfalls das gleiche Resultat ergibt sich, wenn ich ein Signal in der Basisklasse emittiere, dass in der Worker-Klasse aufgefangen wird um selber ein Signal zu emittieren, dass auch vion der Worker-Klasse aufgefangen wird um den Thread aufzuwecken.
Wie also wecke ich einen Thread bzw. meine Worker-Klasse auf?
Vielen Dank,
Johannes
Threadtest_6.h
Code: Alles auswählen
#ifndef THREADTEST_6_H
#define THREADTEST_6_H
#include <QtGui/QMainWindow>
#include "ui_Threadtest_6.h"
#include "Worker.h"
#include <QMutex>
#include <QThread>
class Threadtest_6 : public QMainWindow
{
Q_OBJECT
public:
Threadtest_6(QWidget *parent = 0, Qt::WFlags flags = 0);
~Threadtest_6();
private:
Ui::Threadtest_6Class ui;
QMutex * m_pMutex;
QThread * m_pThread;
Worker * m_pWorker;
signals:
void signalDoWork(void);
void signalWakeWorker(void);
private slots:
void on_pushButton_StartThread_clicked(void);
void slotWorkerData(QString szStatusMessage);
void slotWorkerFinished(void);
};
#endif // THREADTEST_6_HCode: Alles auswählen
#include "Threadtest_6.h"
Threadtest_6::Threadtest_6(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);
}
Threadtest_6::~Threadtest_6()
{
}
void Threadtest_6::on_pushButton_StartThread_clicked()
{
if(ui.pushButton_StartThread->text() == "Start")
{
ui.pushButton_StartThread->setText("Stop");
m_pMutex = new QMutex;
m_pThread = new QThread;
m_pWorker = new Worker(m_pMutex);
m_pWorker->moveToThread(m_pThread);
m_pThread->start();
connect(this, SIGNAL(signalDoWork()), m_pWorker, SLOT(slotDoWork()));
connect(m_pWorker, SIGNAL(signalWorkerData(QString)), this, SLOT(slotWorkerData(QString)));
connect(m_pWorker, SIGNAL(signalWorkerFinished()), this, SLOT(slotWorkerFinished()));
connect(this, SIGNAL(signalWakeWorker()), m_pWorker, SLOT(slotWakeWorker()));
connect(m_pWorker, SIGNAL(signalWake()), m_pWorker, SLOT(slotWake()));
emit signalDoWork();
}
else
{
m_pWorker->m_bIsTracking = false;
}
}
void Threadtest_6::slotWorkerData(QString szStatusMessage)
{
ui.label_StatusMessage->setText(szStatusMessage);
emit signalWakeWorker();
//m_pWorker->slotWakeWorker();
}
void Threadtest_6::slotWorkerFinished(void)
{
m_pThread->exit();
}Code: Alles auswählen
#ifndef WORKER_H
#define WORKER_H
#include <QObject>
#include <time.h>
#include <QWaitCondition>
#include <QMutex>
class Worker :
public QObject
{
Q_OBJECT
public:
Worker(QMutex * pMutex);
~Worker(void);
bool m_bIsTracking;
private:
QMutex * m_pMutex;
QWaitCondition m_WaitCondition;
signals:
void signalWorkerFinished(void);
void signalWorkerData(QString szStatusMessage);
void signalWake(void);
public slots:
void slotDoWork(void);
void slotWakeWorker(void);
void slotWake(void);
};
#endifCode: Alles auswählen
#include "Worker.h"
Worker::Worker(QMutex * pMutex)
{
m_pMutex = pMutex;
m_bIsTracking = true;
}
Worker::~Worker(void)
{
}
void Worker::slotDoWork(void)
{
srand( (unsigned)time( NULL ) );
while(m_bIsTracking)
{
emit signalWorkerData(QString::number((rand()%1000) + 1));
m_WaitCondition.wait(m_pMutex);
}
emit signalWorkerFinished();
}
void Worker::slotWakeWorker()
{
//m_WaitCondition.wakeAll();
emit signalWake();
}
void Worker::slotWake(void)
{
m_WaitCondition.wakeAll();
}