第七十八课、多线程中的信号与槽(上)------------------狄泰软件学院

一、多线程中的信号与槽

1、QThread类拥有发射信号和定义槽函数的能力(因为QThread继承自QObject

(1)、关键信号

A、void start():线程开始运行时发射该信号

B、void finished():线程完成运行时发射该信号

C、void terminated():线程被异常中发射该信号

#ifndef TESTTHREAD_H
#define TESTTHREAD_H

#include <QThread>

class TestThread : public QThread
{
    Q_OBJECT
public:
    explicit TestThread(QObject *parent = 0);
    void run();
    
signals:
    void testsignal();
    
protected slots:
    void testslot();
    
};

#endif // TESTTHREAD_H
TestThread.h
#include "TestThread.h"
#include <QDebug>

TestThread::TestThread(QObject *parent) :
    QThread(parent)
{
    connect(this, SIGNAL(testsignal()), this, SLOT(testslot()));
}

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

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

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

     emit testsignal();//发射信号

     qDebug() << "void TestThread::run() end";
 }
TestThread.cpp
#ifndef MYOBJECT_H
#define MYOBJECT_H

#include <QObject>

class MyObject : public QObject
{
    Q_OBJECT
public:
    explicit MyObject(QObject *parent = 0);
    
signals:
    
protected slots:
    void startslot();
    void finishedslot();
    void terminatedslot();
};

#endif // MYOBJECT_H
MyObject .h
#include "MyObject.h"
#include <QDebug>

MyObject::MyObject(QObject *parent) :
    QObject(parent)
{
}

void MyObject::startslot()
{
    qDebug() << "void MyObject::startslot()";
}
void MyObject::finishedslot()
{
    qDebug() << "void MyObject::finishedslot()";
}
void MyObject::terminatedslot()
{
    qDebug() << "void MyObject::terminatedslot()";
}
MyObject.cpp
#include <QtCore/QCoreApplication>
#include "TestThread.h"
#include "MyObject.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    
    TestThread t;
    MyObject obj;
    QObject::connect(&t, SIGNAL(started()), &obj, SLOT(startslot()));
    QObject::connect(&t, SIGNAL(finished()), &obj, SLOT(finishedslot()));
    QObject::connect(&t, SIGNAL(terminated()), &obj, SLOT(terminatedslot()));


    t.start();

    return a.exec();
}
main.cpp

 2、概念小科普

(1)、进程中存在栈空间的概念(区别于栈数据结构)

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

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

3、小结论:只要函数中没有访问临界资源的代码,同一个函数可以被多个线程调用,且不会产生任何副作用(因为用的自己的栈空间)

4、实验前的准备

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

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

B、线程拥有进程内唯一的ID值(TID

(2)、QThread中关键的静态成员函数

A、QThread* currentThread()

B、Qt::HANDLE currentThreadId()

int main(int argc, char *argv[]) tid
void TestThread::run() 0x56c
TestThread::run() i= 0
void MyObject::startslot() 0x1018  //比TestThread::run() i= 0打印迟,说明线程是并行执行的
TestThread::run() i= 1
TestThread::run() i= 2
TestThread::run() i= 3
TestThread::run() i= 4
TestThread::run() i= 5
TestThread::run() i= 6
TestThread::run() i= 7
TestThread::run() i= 8
TestThread::run() i= 9
void TestThread::run() end
void TestThread::testslot() 0x1018
void MyObject::finishedslot() 0x1018

在主线程、MyThread线程以及各个槽函数加上打印线程的ID号后,打印结果如上所示,发现各个槽函数都是在mian函数被调用(原因请听下回分解

二、小结

(1)、QThread类用于发射信号和定义槽函数的能力

(2)、线程在进程内拥有一个唯一的ID值

(3)、线程拥有独立的栈空间用于函数调用

(4)、没有临界资源的函数可以无副作用被多个线程调用

(5)、槽函数的调用在某一线程中完成 

原文地址:https://www.cnblogs.com/gui-lin/p/6485137.html