Qt如何實現多線程:https://www.cnblogs.com/azbane/p/11372531.html
September 5,2019
先拋出幾個問題,用問題來引導思維導向:
1、繼承的QObject子類,和QThread對象,是在哪個線程創建的?(即:QObject子類對象和QThread對象的依附線程是哪個?)
2、QThread在哪個線程運行?
3、QObject::moveToThread( QThread )后,QThread 的信號(started/finished)關聯的QObject子類對象的函數(槽函數)哪個線程運行?
4、QObject::moveToThread( QThread ) 后,QThread的信號(started/finished)關聯的依附線程對象的槽函數在哪個線程運行?
5、信號和槽的新版本,用lambda表達式處理信號的情況(QThread的信號(started/finished)關聯的lambda),lambda對象運行在哪個對象?
看起來很復雜,其實並不可怕:想知道對象在哪個線程運行,有兩種方式可用
1:QThread::currentThreadId() 返回16進制的線程ID (#include<QThread>)
2:std::this_thread::get_id() 返回10進制的線程ID (#include<iostream> #include <QThread>)
先給答案,再上例子說明, 最后給出遇到的錯誤情況。
上面跑出的5個問題的答案:
假定QObject子類對象和QThread對象都是在線程A中創建。
1、線程A。 調用std::this_thread::get_id
2、線程A。 調用QThread::currentThreadId, 需要由16進制轉成10進制,再對比。
3、線程B。 假定線程id = B 。調用std::this_thread::get_id
4、線程A。 調用std::this_thread::get_id
5、線程B。 調用std::this_thread::get_id
例子主要信息說明:
類ShapeLayout:
有兩個指針數據成員:GenerateGridFileWork * m_generateGridFileWork; QThread * m_generateGridFileWorkThread;
有一個函數成員:MakeGrid, 函數里面創建兩個指針數據成員。
m_generateGridFileWork->moveToThread(m_generateGridFileWorkThread);
GenerateGridFileWork::slotsWork
QThread::signals - started / finished
ShapeLayout.h ----------------------------------------------------------- class ShapeLayout : public QObject { Q_OBJECT public: void makeGrid(); public slots: void slotsThreadFininshed(); private: GenerateGridFileWork * m_GenerateGridFileWork = nullptr; QThread * m_GenerateGridFileWorkThread = nullptr; } ShapeLayout.cpp ----------------------------------------------------------- void ShapeLayout::makeGrid() {
std::cout<<"ShapeLayout thread id is "<<std::this_thread::get_id()<<std::cout; //問題-1 m_GenerateGridFileWork = new GenerateGridFileWork ; m_GenerateGridFileWorkThread = new QThread; m_GenerateGridFileWork->moveToThread(m_GenerateGridFileWorkThread); QObject::connect(m_GenerateGridFileWorkThread, &QThread::started, m_GenerateGridFileWork , &GenerateGridFileWork::slotsWork); QObject::connect(m_GenerateGridFileWork, &GenerateGridFileWork::signalsWorkFinished, m_GenerateGridFileWorkThread, &QThread::quit); QObject::connect(m_GenerateGridFileWorkThread, &QThread::finished, this, &ShapeLayout::slotsThreadFininshed); QObject::connect(m_GenerateGridFileWorkThread, &QThread::started, []{ std::cout<<"connect thread-started signals lambda object thread id is"<<std::this_thread::get_id()<<std::cout; //問題-5 }); QObject::connect(m_GenerateGridFileWorkThread, &QThread::finished, []{ std::cout<<"connect thread-finishedsignals lambda object thread id is"<<std::this_thread::get_id()<<std::cout;//問題-5
});
std::cout<<"QThread thread id is "<<m_generateGridFileWorkThread->currentThreadId()<<std::cout; //問題-2
m_GenerateGridFileWorkThread->start();
}
void ShapeLayout::slotsThreadFininshed()
{
std::cout<<"connect slots function of the ShapeLayout attributable thread id is"<<std::this_thread::get_id()<<std::cout;//問題-4
}
GenerateGridFileWork.h ------------------------------------------------ class GenerateGridFileWork : public QObject { public slots: void slotsWork(); signals: void signalsWorkFinished(); } GenerateGridFileWork.cpp ------------------------------------------------ void GenerateGridFileWork::slotsWork() { std::cout<<"connect to slots function of QObject subObject thread id is "<<std::this_thread::get_id()<<std::cout;//問題-3 emit signalsWorkFinished(); }
調用ShapeLayout::makeGrid(); 一切都知道啦, 自己去運行一遍吧
OK perfect...
September 5, 2019追加一個問題:
moveToThread的方式實現的線程,作業完成后,針對QObject的子類對象和QThread對象的釋放順序有沒有講究?