zoukankan      html  css  js  c++  java
  • 第七十八课、多线程中的信号与槽(上)------------------狄泰软件学院

    一、多线程中的信号与槽

    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)、槽函数的调用在某一线程中完成 

  • 相关阅读:
    DBAccess
    业务耗时及数组
    QB资料学习.01
    格式化参数
    日志记录.02_线程处理
    nginx 开启gzip
    js 变量提升和函数提升
    js 深拷贝 vs 浅拷贝
    js 伪数组 转 数组
    js 对象原型和原型链
  • 原文地址:https://www.cnblogs.com/gui-lin/p/6485137.html
Copyright © 2011-2022 走看看