使qthread成为单例消耗大量的CPU负载

时间:2014-11-24 06:27:53

标签: qt qthread

我试图将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收到的信号。

1 个答案:

答案 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();
}