2014-11-24 99 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