QThread question - QThread::currentThread() gives 3 different addresses
-
Hi,
i am a little bit confused using threads.In my code i creataed a AMQTest class which is inherited from QThread.
I put debug output with the threadID into constructor, run method
and in a callback method which gets called if a new mesasges has been received (via activemq).What i do not understand is, why do i get 3! different addresses when logging the @QThread::currentThread()@ ??
For example in constructor i get:
*AMQTest::AMQTest: threadID= QThread(0x756ba0) *
Then in run() ---> which should be the thread? it get:
STARTING RUN: threadID= QThread(0x7fffbdc3acc8, name = "AMTTest - MAIN")
and last but not least in my callback i get:
AMQTest message: threadID= QThread(0x7f3298000d90) nreceivedMessages= 1
This are 3 different addresses for @QThread::currentThread()@
0x756ba0
0x7fffbdc3acc8
0x7f3298000d90
Could somebody please explain me what happens here?
Here is a piece of demo code:
@AMQTest::AMQTest() :
m_brokerURI("tcp://192.168.0.10:61616"),
m_destURI("lasttest"),
m_clientAck(false)
{
qDebug() << "=================================================";
qDebug() << "AMQTest::AMQTest: threadID=" << QThread::currentThread();
qDebug() << "=================================================";QThread::start(); qDebug() << "================================================="; qDebug() << "BYE BYE!"; qDebug() << "=================================================";
}
AMQTest::~AMQTest()
{
qDebug() << "~AMQTest threadID=" << QThread::currentThread();qDebug() << "~AMQTest: Shutting down thread... threadID=" << QThread::currentThread(); QThread::wait(); qDebug() << "~AMQTest: Thread shutdown completede! threadID=" << QThread::currentThread();
}
bool AMQTest::initialize()
{
qDebug() << "initialize: threadID=" << QThread::currentThread();
qDebug() << "brokerURI = " << m_brokerURI;
qDebug() << "destURI = " << m_destURI;try { activemq::core::ActiveMQConnectionFactory *connectionFactory = new activemq::core::ActiveMQConnectionFactory(m_brokerURI.toStdString()); m_cmsConnection = connectionFactory->createConnection(); qDebug() << "created connection from connection factory"; delete connectionFactory; activemq::core::ActiveMQConnection *connection = dynamic_cast<activemq::core::ActiveMQConnection *>(m_cmsConnection); connection->start(); //connection->setExceptionListener(this); qDebug() << "succsessdully connected to broker: " << m_brokerURI; m_clientAck ? m_session = m_cmsConnection->createSession(cms::Session::CLIENT_ACKNOWLEDGE) : m_session = m_cmsConnection->createSession(cms::Session::AUTO_ACKNOWLEDGE); m_useTopic ? m_destination = m_session->createTopic(m_destURI.toStdString()) : m_destination = m_session->createQueue(m_destURI.toStdString()); m_consumer = m_session->createConsumer(m_destination); m_consumer->setMessageListener(this); } catch (cms::CMSException& e) { printException(e); return false; } return true;
}
void AMQTest::run()
{
qDebug() << "STARTING RUN: threadID=" << QThread::currentThread();if(!initialize()) return; exec(); qDebug() << "LEAVING RUN: threadID=" << QThread::currentThread(); qApp->quit();
}
void AMQTest::onMessage(const cms::Message *message) throw ()
{
static qlonglong received = 0;++received; if(received > MAX_MESSAGES) { qDebug() << "max messages: " << MAX_MESSAGES << " received -> stopping thread"; QThread::exit(1); return; } qDebug() << "AMQTest message: threadID=" << QThread::currentThread() << " nreceivedMessages=" << received; //const cms::TextMessage *textMsg = dynamic_cast<const cms::TextMessage *>(message); //qDebug() << textMsg->getText().c_str();
}
void AMQTest::printException(const cms::CMSException &e)
{
qDebug() << "======== ActiveMQ Exception ========";
qDebug() << QString::fromStdString(e.getStackTraceString());
qDebug() << QString::fromStdString(e.what());
qDebug() << QString::fromStdString(e.getMessage());
qDebug() << "=====================================";
}@Thank you
-
Hi,
The thread of the constructor is the thread where you instantiate your object
The thread in the run function, is your QThread's managed thread.
The thread of the callback is the thread that is calling the callback function
Hope it helps
-
Hi,
QThread::currentThread() is a static function. Its return value depends on the thread that calls it.
QThread is not a thread. It is an object that manages a thread. You can say that a QThread straddles 2 threads:
- The QThread object is constructed in one thread, so it lives in this thread, but
- Its run() function executes in a different thread
[quote]
0×756ba0
0×7fffbdc3acc8
0×7f3298000d90
[/quote]Pointer #1 is very far away from pointers #2 and #3. I'm not sure if it is valid.
Questions:
Where did you construct your AMQTest?
What is onMessage() connected to, and how is it connected?
Do you have any other threads in your program?
By the way, your AMQTest class does lots of processing. Thus, it should be a subclass of QObject, not QThread. This is especially important since you want to use a slot (onMessage()) -- QThread subclasses should never use new slots to do processing.
Quoting from the "QThread documentation":http://qt-project.org/doc/qt-5.1/qtcore/qthread.html:
"It is important to remember that a QThread object usually lives in the thread where it was created, not in the thread that it manages. This oft-overlooked detail means that a QThread's slots will be executed in the context of its home thread, not in the context of the thread it is managing. For this reason, implementing new slots in a QThread subclass is error-prone and discouraged."
-
I also highly recommend reading this page for an overview on different ways to use threads in Qt: http://doc-snapshot.qt-project.org/qt5-stable/threads-technologies.html