多线程中的信号与槽(上)

值得思考的问题:

 线程类的信号与槽

 实验一:

TestThread.h

#ifndef TESTTHREAD_H
#define TESTTHREAD_H

#include <QThread>

class TestThread : public QThread
{
    Q_OBJECT
protected:
    void run();
public:
    TestThread();

signals:
    void testSignal();
protected slots:
    void testSlot();
};

#endif // TESTTHREAD_H
复制代码
#ifndef TESTTHREAD_H
#define TESTTHREAD_H

#include <QThread>

class TestThread : public QThread
{
    Q_OBJECT
protected:
    void run();
public:
    TestThread();

signals:
    void testSignal();
protected slots:
    void testSlot();
};

#endif // TESTTHREAD_H
复制代码

TestThread.cpp

#include "TestThread.h"
#include <QDebug>

TestThread::TestThread()
{
    connect(this,SIGNAL(testSignal()),this,SLOT(testSlot()));
}

void TestThread::run()
{
   qDebug() << "void TestThread::run() begin...";

   for(int i=0; i<10; i++)
   {
       qDebug() << "void TestThread::run() i = " << i;
       sleep(1);
   }

   emit testSignal(); //发射的信号谁来接收呢,可以在构造函数中将信号和槽函数进行关联。

   qDebug() << "void TestThread::run() end...";
}

void TestThread::testSlot()
{
    qDebug() << "void TestThread::testSlot()";
}

main.cpp

#include <QCoreApplication>
#include "TestThread.h"


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    TestThread t;

    t.start();
    return a.exec();
}

 实验二:在上面实验的基础上增加类MyObject.h

MyObject.h

#ifndef MYOBJECT_H
#define MYOBJECT_H
#include <QObject>


class MyObject : public QObject
{
    Q_OBJECT
public:
    MyObject();
protected slots:
    void getStarted();
    void getFinished();
    void getTeminated();
};

#endif // MYOBJECT_H

MyObject.cpp

#include "MyObject.h"
#include <QObject>
#include <QDebug>

MyObject::MyObject()
{

}

void MyObject::getStarted()
{
    qDebug() <<"void MyObject::getStarted()" ;
}

void MyObject::getFinished()
{
    qDebug() << "void MyObject::getFinished()";
}

void MyObject::getTeminated()
{
    qDebug() << "void MyObject::getTeminated()";
}

main.cpp

#include <QCoreApplication>
#include "TestThread.h"
#include "MyObject.h"


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    TestThread t;
    MyObject m;

    QObject::connect(&t,SIGNAL(started()),&m,SLOT(getStarted()));
    QObject::connect(&t,SIGNAL(finished()),&m,SLOT(getFinished()));
 //   QObject::connect(&t,SIGNAL(terminated()),&m,SLOT(getTeminated()));

    t.start();
    return a.exec();
}

 

让人逃避的问题: 

问题:如果程序中有多个线程,槽函数是在哪个线程中执行?

概念小科普

进程中存在栈空间的概念

栈空间专用于函数调用(保存函数参数,局部变量,等)

线程拥有独立的栈空间(可调用其他函数)

小结论:

只要函数体中没有访问临界资源的代码,同一个函数可以被多个线程同时调用,且不会产生任何副作用。

实验前的准备:

操作系统通过整型标识管理进程和线程

进程拥有全局唯一的ID值(PID)

线程有进程内唯一的ID值(TID)

QThread中的关键静态成员函数

QThread* currentThread()

Qt::HANDLE currentThreadId()

槽函数的运行上下文

main.cpp

#include <QCoreApplication>
#include <QThread>
#include <QDebug>
#include "TestThread.h"
#include "MyObject.h"


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    qDebug() << "main tid() " << QThread::currentThreadId();

    TestThread t;
    MyObject m;

    QObject::connect(&t,SIGNAL(started()),&m,SLOT(getStarted()));
    QObject::connect(&t,SIGNAL(finished()),&m,SLOT(getFinished()));
 //   QObject::connect(&t,SIGNAL(terminated()),&m,SLOT(getTeminated()));

    t.start();
    return a.exec();
}

MyObject.cpp

#include "MyObject.h"
#include <QObject>
#include <QThread>
#include <QDebug>

MyObject::MyObject()
{

}

void MyObject::getStarted()
{
    qDebug() <<"void MyObject::getStarted()tid = " << QThread::currentThreadId() ;
}

void MyObject::getFinished()
{
    qDebug() << "void MyObject::getFinished()tid = " << QThread::currentThreadId() ;
}

void MyObject::getTeminated()
{
    qDebug() << "void MyObject::getTeminated()tid = " << QThread::currentThreadId() ;
}

TestThread.cpp

#include "TestThread.h"
#include <QDebug>

TestThread::TestThread()
{
    connect(this,SIGNAL(testSignal()),this,SLOT(testSlot()));
}

void TestThread::run()
{
   qDebug() << "void TestThread::run() begin...tid = " << currentThreadId();

   for(int i=0; i<10; i++)
   {
       qDebug() << "void TestThread::run() i = " << i;
       sleep(1);
   }

   emit testSignal(); //发射的信号谁来接收呢,可以在构造函数中将信号和槽函数进行关联。

   qDebug() << "void TestThread::run() end...";
}

void TestThread::testSlot()
{
    qDebug() << "void TestThread::testSlot() tid = " << currentThreadId();
}
复制代码
#include "TestThread.h"
#include <QDebug>

TestThread::TestThread()
{
    connect(this,SIGNAL(testSignal()),this,SLOT(testSlot()));
}

void TestThread::run()
{
   qDebug() << "void TestThread::run() begin...tid = " << currentThreadId();

   for(int i=0; i<10; i++)
   {
       qDebug() << "void TestThread::run() i = " << i;
       sleep(1);
   }

   emit testSignal(); //发射的信号谁来接收呢,可以在构造函数中将信号和槽函数进行关联。

   qDebug() << "void TestThread::run() end...";
}

void TestThread::testSlot()
{
    qDebug() << "void TestThread::testSlot() tid = " << currentThreadId();
}
复制代码

 从上面的打印结果看,槽函数的执行都是在主线程中执行的,但事实真的如此吗?后续将会继续讨论。

原文地址:https://www.cnblogs.com/bruce1992/p/14320919.html