当前位置: 首页 > news >正文

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

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

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\n");
        file.fileWrite("你好,世界\n");
        file.fileWrite("狄泰软件学院,成就梦想\n");
        file.fileClose();
    }
    
    return a.exec();
}
main.cpp

三、小结

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

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

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

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

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

转载于:https://www.cnblogs.com/gui-lin/p/6498127.html

相关文章:

  • Eclipse在线安装hibernate tools插件
  • Laravel 实践之路: 数据库迁移与数据填充
  • Git与TortoiseGit基本操作
  • CHIL-ORACLE-创建非空约束
  • JavaScript思维导图之字符串函数
  • JS实现OO机制
  • Sql Server数据批量更新
  • Linux usb子系统(一) _写一个usb鼠标驱动
  • SylixOS iMX6平台I2C总线驱动
  • HTML初学者常用标签及属性
  • jquery特效 商品SKU属性规格选择实时联动
  • centos
  • Greenplum 简单性能测试与分析
  • 智障的对话
  • 一维数组打乱顺序shuffle函数
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • 【跃迁之路】【669天】程序员高效学习方法论探索系列(实验阶段426-2018.12.13)...
  • css布局,左右固定中间自适应实现
  • CSS魔法堂:Absolute Positioning就这个样
  • github从入门到放弃(1)
  • in typeof instanceof ===这些运算符有什么作用
  • JavaScript DOM 10 - 滚动
  • Javascript Math对象和Date对象常用方法详解
  • Joomla 2.x, 3.x useful code cheatsheet
  • Less 日常用法
  • Ruby 2.x 源代码分析:扩展 概述
  • Sequelize 中文文档 v4 - Getting started - 入门
  • SwizzleMethod 黑魔法
  • 从0实现一个tiny react(三)生命周期
  • 从零到一:用Phaser.js写意地开发小游戏(Chapter 3 - 加载游戏资源)
  • 大数据与云计算学习:数据分析(二)
  • 分享一个自己写的基于canvas的原生js图片爆炸插件
  • 开发基于以太坊智能合约的DApp
  • 前端每日实战 2018 年 7 月份项目汇总(共 29 个项目)
  • 浅谈Kotlin实战篇之自定义View图片圆角简单应用(一)
  • 如何胜任知名企业的商业数据分析师?
  • 实战:基于Spring Boot快速开发RESTful风格API接口
  • 突破自己的技术思维
  • 一个SAP顾问在美国的这些年
  • 译自由幺半群
  • 原生 js 实现移动端 Touch 滑动反弹
  • 如何正确理解,内页权重高于首页?
  • ​插件化DPI在商用WIFI中的价值
  • ​批处理文件中的errorlevel用法
  • #我与Java虚拟机的故事#连载05:Java虚拟机的修炼之道
  • (Python第六天)文件处理
  • (二)linux使用docker容器运行mysql
  • (附源码)ssm基于微信小程序的疫苗管理系统 毕业设计 092354
  • (机器学习-深度学习快速入门)第一章第一节:Python环境和数据分析
  • (南京观海微电子)——COF介绍
  • (未解决)jmeter报错之“请在微信客户端打开链接”
  • (转)从零实现3D图像引擎:(8)参数化直线与3D平面函数库
  • (转)母版页和相对路径