zoukankan      html  css  js  c++  java
  • 多线程中的信号与槽(上)

    值得思考的问题:

     线程类的信号与槽

     实验一:

    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
    View Code

    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()";
    }
    View Code

    main.cpp

    #include <QCoreApplication>
    #include "TestThread.h"
    
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        TestThread t;
    
        t.start();
        return a.exec();
    }
    View Code

     实验二:在上面实验的基础上增加类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
    View Code

    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()";
    }
    View Code

    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();
    }
    View Code

     

    让人逃避的问题: 

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

    概念小科普

    进程中存在栈空间的概念

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

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

    小结论:

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

    实验前的准备:

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

    进程拥有全局唯一的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();
    }
    View Code

    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() ;
    }
    View Code

    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();
    }
    View Code

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

  • 相关阅读:
    使用json序列化类型为“ajax学习.DataSetComment+T_CommentDataTable”的对象时检测到循环引用。
    CKEditor在asp.net上使用的图例详解
    去掉 win7 “测试模式 windows7 内部版本7601” 字样
    Java中非静态方法是否共用同一块内存?
    最长公共子串(LCS)
    [链表]复杂链表的复制
    最长公共子序列
    最大子序列和问题
    [ 队列]从上往下遍历二元树
    [链表]在O(1)时间删除链表结点
  • 原文地址:https://www.cnblogs.com/-glb/p/13460919.html
Copyright © 2011-2022 走看看