QThread 采用moveToThread方式實現多線程。 線程本身、connect關聯的槽函數、connect關聯的lambda對象分別運行在哪個線程中。


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對象的釋放順序有沒有講究?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM