2014-11-24 102 views
0

即时通讯尝试在我的项目的不同对象中具有qthread的范围。所以我试图让线程成为一个单身人士。它是一个用作客户端的DBUS接口。使qthread作为单身人士消耗大量的CPU负荷

这是我实施的代码。 .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-> start();

CPU负载超过PC的100%。即时消息只在主类中启动线程。剩下的课只是宣布和使用DBUS收到的信号。

+0

使用'qDebug()<<的QThread :: currentThreadId();'检查如果你的代码运行在一个单独的线程中或者没有运行 – Zaiborg 2014-11-24 06:36:00

+0

当然代码是作为单独的线程运行的。它不会阻止我的GUI流程,并且还会重新考虑我对注释线程的怀疑,并仅检查GUI。没关系..只有线程给CPU的负载更大.. – Wagmare 2014-11-24 06:48:41

+2

我还没有重写QThreads的运行方法,所以我只能假设问题出现在while循环中。我通常使用一个工作对象,使用'QObject :: moveToThread()'移动到特定的线程。 – Zaiborg 2014-11-24 06:56:54

回答

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(); 
} 
+0

我会尝试你的建议galinette,并尽快给你结果..谢谢.. – Wagmare 2014-11-24 09:33:32

+0

@galinette,为什么使用静态QThread?是否可能有多个ClientDBusThread对象? – TheDarkKnight 2014-11-24 09:36:02

+0

成为他想要的单身模式,这是在标题。所以,是的,该作者只需要一个ClientDBusThread。 在其他情况下,每个对象都有一个非静态QThread,是 – galinette 2014-11-24 09:38:34