我试图将qthread的范围放在我项目的不同对象中。所以我试图让线程成为单身人士。它是一个用作客户端的DBUS接口。
这是我实现的代码。 .H
class ClientDBUSThread : public QThread
{
Q_OBJECT
public:
static ClientDBUSThread *getInstance();
void messageReceived(QString );
private:
ClientDBUSThread();
static ClientDBUSThread *instance;
static QMutex instanceMutex;
void run();
signals:
void signalReceivedInDBUS(QString);
public Q_SLOTS:
void mySlot(QString);
void stop();
private:
DemoIf* client ;
QMutex m_mutex;
bool m_stop;
};
和.cpp
#include "ClienDBusThread.h"
#include <QMap>
ClientDBUSThread *ClientDBUSThread::instance(0);
QMutex ClientDBUSThread::instanceMutex;
ClientDBUSThread *ClientDBUSThread::getInstance()
{
if (!instance) {
QMutexLocker instanceMutexLocker(&instanceMutex);
if (!instance) {
instance = new ClientDBUSThread();
}
}
return instance;
}
ClientDBUSThread::ClientDBUSThread()
{
m_stop = false;
client = new DemoIf("com.nokia.Demo", "/", QDBusConnection::sessionBus(), 0);
connect(client, SIGNAL(LateEvent(QString)), this, SLOT(mySlot(QString)));
QDBusConnection cnn= client->connection();
qDebug()<<"is the DBUS gets connected:"<<cnn.isConnected();
const QMap<QString, QVariant> hi;
client->SayHello("HELLO THERE HOW ARE YOU", hi);
client->SayBye();
}
void ClientDBUSThread::run()
{
while (1) {
QMutexLocker locker(&m_mutex);
if (m_stop) break;
}
}
void ClientDBUSThread::stop()
{
QMutexLocker locker(&m_mutex);
m_stop=true;
client->SayBye();
}
void ClientDBUSThread::messageReceived(QString message)
{
const QMap<QString, QVariant> hi;
client->SayHello(message, hi);
}
void ClientDBUSThread::mySlot(QString data)
{
emit signalReceivedInDBUS(data);
}
同时声明像
这样的对象theDBUSThread = ClientDBUSThread :: getInstance(); 它很好但是在启动线程时
theDBUSThread-&GT;开始();
CPU负载超过PC的100%。我只在主类中启动线程。其余的类我只是声明并使用DBUS收到的信号。
答案 0 :(得分:2)
只有你的run()循环代码在线程中执行。如果代码在触发时没有运行插槽的事件循环,那么你如何期望代码运行呢?
在这种情况下,你不应该从QThread继承。
相反,从QObject派生你的类。
class ClientDBUSThread : public QObject
{
Q_OBJECT
public:
static ClientDBUSThread *getInstance();
void messageReceived(QString );
private:
ClientDBUSThread();
static ClientDBUSThread *instance;
static QThread * thread;
static QMutex instanceMutex;
//void run(); //removed
signals:
void signalReceivedInDBUS(QString);
public Q_SLOTS:
void startup();
void mySlot(QString);
void stop();
private:
DemoIf* client ;
QMutex m_mutex;
bool m_stop;
};
在GetInstance()中创建一个静态QThread实例以及您的主类。然后将后者移动到线程:
ClientDBUSThread *ClientDBUSThread::getInstance()
{
if (!instance) {
QMutexLocker instanceMutexLocker(&instanceMutex);
if (!instance) {
//You will need to destroy these somewhere
instance = new ClientDBUSThread();
thread = new QThread();
instance->moveToThread(thread);
connect(thread, SIGNAL(started()), instance, SLOT(startup()));
//the thread is not started yet, you need to thread->start() somewhere
}
}
return instance;
}
然后,不是在构造函数中,而是在启动时执行启动作业
void ClientDBUSThread::ClientDBUSThread()
{
//I supposed that last argument of DemoIf constructor
//is the pointer to parent. It may be a good idea to parent it with this,
//So I replaced 0 by this
client = new DemoIf("com.nokia.Demo", "/", QDBusConnection::sessionBus(), this);
connect(client, SIGNAL(LateEvent(QString)), this, SLOT(mySlot(QString)));
}
void ClientDBUSThread::startup()
{
m_stop = false;
QDBusConnection cnn= client->connection();
qDebug()<<"is the DBUS gets connected:"<<cnn.isConnected();
const QMap<QString, QVariant> hi;
client->SayHello("HELLO THERE HOW ARE YOU", hi);
client->SayBye();
}