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


    一、线程体函数开启了事件循环,线程如何正常结束

    1、QThread::exec()使得线程进入事件循环

    (1)、事件循环结束前,exec()后的语句无法执行

    (2)、quit()和exit()函数用于结束事件循环

    (3)、quit() <---->exit(0),exec()的返回值由exit()参数决定

    2、注意

    (1)、无论事件循环是否开启,信号发送后会直接进入所依附线程的事件队列

    (2)、然而,只有开启了事件循环对应的槽函数才会在线程中被调用 

    二、什么时候需要开启事件循环

    1、设计原则

    (1)、事务性操作(间断性IO操作,等)可以开启线程的事件循环

    (2)、每次操作通过发送信号的方式使得槽函数在子线程中执行

    2、概念小科普:文件缓冲区(文件操作是事务性操作

    (1)、默认情况下,文件操作时会开辟一段内存作为缓冲区

    (2)、向文件中写入的数据会先进入缓冲区

    (3)、只有当缓冲区满或者遇到换行符时才将数据写入磁盘

    (4)、缓冲区的意义在于:减少磁盘的低级IO操作,提高文件读写效率(但存在风险)

    3、Qt线程的使用模式

    (1)、无事件循环模式:后台执行常时间的耗时任务(文件复制、网络读取等)

     (2)、开启事件循环模式:执行事务性操作(文件写入,数据库写入等)

    开启一个线程,线程里边只需要开启事件循环,然后将槽函数,通过对象的依附性转移来将槽函数移到线程执行,最后不要忘了在析构函数中终止线程的执行

    #ifndef FILEWRITE_H
    #define FILEWRITE_H
    
    #include <QObject>
    #include <QFile>
    #include <QString>
    #include <QThread>
    
    class FileWrite : public QObject
    {
        Q_OBJECT
    
    private:
        class writeThread : public QThread//记得是public继承
        {
        protected:
            void run();
        };
        QFile* m_file;
        writeThread thread;
    
    public:
        explicit FileWrite(QString path, QObject *parent = 0);
        bool fileOpen();
        void fileWrite(const char* text);
        void fileClose();
    
    signals:
        void testWrite(const char* text);
        void testClose();
    
    protected slots:
        void writeSlot(const char* text);
        void closeSlot();
    
    
    };
    
    #endif // FILEWRITE_H
    FileWrite.h
    #include "FileWrite.h"
    #include <QIODevice>
    #include <QDebug>
    
    FileWrite::FileWrite(QString path, QObject *parent) :
        QObject(parent)
    {
        m_file = new QFile(path, this);
    
        connect(this, SIGNAL(testWrite(const char*)), this, SLOT(writeSlot(const char*)));
        connect(this, SIGNAL(testClose()), this, SLOT(closeSlot()));
    
        moveToThread(&thread);//这句话极其重要,将槽函数移到线程中执行
    
        thread.start();
    }
    
    bool FileWrite::fileOpen()
    {
        return m_file->open(QIODevice::WriteOnly | QIODevice::Text);
    }
    void FileWrite::fileWrite(const char* text)
    {
        emit testWrite(text);
    }
    void FileWrite::fileClose()
    {
        emit testClose();
    }
    FileWrite::~FileWrite()//析构函数中终止线程执行
    {
        thread.quit();
    }
    
    /**************************************槽函数******************************************/
    void FileWrite::writeSlot(const char* text)
    {
        qDebug() << "void FileWrite::writeSlot(const char* text) tid = " << QThread::currentThreadId();
    
        m_file->write(text);
        m_file->flush();//每次写的时候都直接写入文件,进行低级的IO操作,比较耗时
    }
    void FileWrite::closeSlot()
    {
        qDebug() << "void FileWrite::closeSlot() tid= " << QThread::currentThreadId();
    
        m_file->close();
    }
    /***********************************线程的函数*****************************************/
    void FileWrite::writeThread::run()
    {
        qDebug() << "void FileWrite::writeThread::run() tid= " << QThread::currentThreadId();
        exec();
    }
    FileWrite.cpp
    #include <QtCore/QCoreApplication>
    #include "FileWrite.h"
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        FileWrite file("C:/Users/LGC/Desktop/test.txt");
    
        if(file.fileOpen());
        {
            file.fileWrite("Hello word
    ");
            file.fileWrite("你好,世界
    ");
            file.fileWrite("狄泰软件学院,成就梦想
    ");
            file.fileClose();
        }
        
        return a.exec();
    }
    main.cpp

    三、小结

    (1)、QThread::exec()使得线程进入事件循环

    (2)、quit() <---->exit(0)用于结束线程的事件循环并返回

    (3)、事务性操作可以开启线程的事件循环将操作分摊到子线程

    (4)、工程开发中,多数情况不会开启线程的事件循环

    (5)、线程多用于执行后台任务或者耗时操作

  • 相关阅读:
    idea常用快捷键
    Spring中<bean>标签之使用p标签配置bean的属性
    Mysql语句转义
    Idea使用(摘抄至java后端技术公众号-孤独烟)
    js中scroll滚动相关
    Flask-wtforms类似django中的form组件
    Flask中的数据连接池
    SQLAlchemy
    博客园美化阅读模式
    [NOIP2003] 提高组 洛谷P1039 侦探推理
  • 原文地址:https://www.cnblogs.com/gui-lin/p/6498127.html
Copyright © 2020-2023  润新知