• 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对象的释放顺序有没有讲究?

  • 相关阅读:
    background及background-size
    -ms-,-moz-,-webkit-,-o-含义
    &:first-of-type含义
    ES6的Promise对象
    LightOJ 1029 Civil and Evil Engineer最小生成树和最大生成树
    快速幂模板
    poj2965 The Pilots Brothers' refrigerator 枚举或DFS
    poj1753Flip Game(枚举+DFS)
    POJ 1751Highways
    HDU 1875 畅通工程再续 prim模板题
  • 原文地址:https://www.cnblogs.com/azbane/p/11465466.html
Copyright © 2020-2023  润新知