值得思考的问题:
线程类的信号与槽
实验一:
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();
}
从上面的打印结果看,槽函数的执行都是在主线程中执行的,但事实真的如此吗?后续将会继续讨论。