Qt 多线程编程之入门

本文介绍了Qt中的多线程编程,包括线程的基础知识、QThread的使用,如基础、继承QThread和moveToThread(),以及线程同步的多种方法,如互斥量、QReadWriteLock、QWaitCondition和信号量的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

多线程在实际项目编程中是非常常用的,下面按照以下几点进行介绍:

  1. 线程介绍
  2. QThread介绍
  3. 线程同步

正文

1. 线程介绍

因为进程的创建、切换需要大量的时间和空间的消耗,因此在上世纪80年代诞生了一种SMP(Symmetrical Multi-Processing)的对称多处理技术,这就是线程。
线程的创建、切换所需的消耗要比进程小很多,这是因为进程需要一块完整的地址空间,而线程只是进程中的最小执行单元,共享进程的地址空间,不需要创建新的资源。

1.1 线程和进程的区别
区别 线程 进程
根本区别 是处理器任务调度和执行的最小单位 是操作系统资源调度的最小单位
资源开销 同进程下的线程共享进程的资源 进程之间的资源相互独立
包含关系 线程是进程的最小执行单元 进程包含多个线程
1.2 线程调度

Windows操作系统在启动后就会开始检查可调度线程内核对象,选择一个线程的内核对象,将其上下文载入CPU寄存器,然后线程开始运行。
线程的调度机制是由调度算法决定的,通用调度算法有:

  1. 先进先出算法(FIFO)
    按照任务进入队列的顺序,依次调度。

  2. 最短耗时任务优先算法(SJF)
    按照任务的耗时长短进行调度,耗时短的任务优先调度。

  3. 时间片轮转算法(Round Robin)
    给队列中的每个任务一个时间片,第一个任务先执行,时间片结束后将任务放到队列末尾,然后切换到下个任务执行。

  4. 最大最小公平算法(Max-Min Fairness)
    平均分配资源;
    有剩余资源的则平均分配给其他任务;
    资源不够则等待;

  5. 多级反馈队列算法(Multi-level Feedback Queue)
    算法按照优先级从高到低排序,优先级越低分片时长越大;
    高优先级任务可以抢占低优先级任务;
    任务在一个时间片结束时,若任务结束,则正常退出系统,若任务还没结束,则降低一个等级;
    任务如果因为等待I/O响应而主动让出CPU,则保留当前等级(或者是提高一个等级);
    同一等级的任务采用时间片轮转算法(Round Robin);

2. QThread介绍

QThread类提供不依赖平台的管理线程的方法。一个QThread类的对象管理一个线程,一般实现方式有两种:

  • 继承QThread类,并重定义虚函数run(),在run()函数实现耗时任务
  • 继承QObject类,自定义槽函数实现耗时任务,通过moveToThread来改变对象的线程亲和力
2.1 QThread基础

QThread是Qt线程中的抽象类,所有的线程类都是从QThread抽象类中派生出来的。
下面列举主要函数:

类型 函数 功能
public void setPriority(Priority priority) 设置线程的优先级
public void exit(int returenCode = 0) 退出线程的事件循环
public bool wait(unsigned long time) 阻塞等待线程结束,直到time毫秒后
public slot void quit() 退出线程的事件循环
public slot void start(Priority priority) 内部调用run()开始执行线程,操作系统根据priority参数进行调度
public slot void terminate() 终止线程的运行,不是立即结束线程,而是等待操作系统结束线程。使用terminate()之后应使用wait()
signal void finished() 在线程结束时发送该信号
signal void started() 在线程开始执行时,run()被调用之前发送该信号
protected virtual void run() start()调用run()开始线程任务的执行,在run()中实现线程的处理任务
protected int exec() 由run()调用,进入线程的事件循环,等待exit()退出

QThread线程有8个优先级:

优先级 注释
QThread::IdlePriority 仅在没有其他线程运行的情况下执行
QThread::LowestPriority 优先级低于LowPriority
QThread::LowPriority 优先级低于NormalPriority
QThread::NormalPriority 操作系统的默认优先级
QThread::HighPriority 优先级高于NormalPriority
QThread::HighestPriority 优先级高于HighPriority
QThread::TimeCriticalPriority 尽可能频繁运行
QThread::InheritPriority 使用与创建线程相同的优先级(默认)
2.2 继承QThread类

按照官网的介绍,主要是以下两点:

  • 不在run()中调用exec(),就不会运行事件循环
  • QThread派生的实例对象除了run()在新线程中执行外,其他(构造函数、槽函数等)都在创建该对象的线程中执行

下面测试一下:

class WorkerThd : public QThread
{
   
	Q_OBJECT

public:
	WorkerThd(QObject* parent = nullptr) : QThread(parent) {
   }
	void run() override {
   
		qDebug() << "ThreadID of the run(): " << QThread::currentThreadId();
	}

	Q_SLOT void doOtherWork() {
   
		qDebug() << "ThreadID of the doOtherWork(): " << QThread::currentThreadId();
	}
};

class Controller : public QObject
{
   
	Q_OBJECT
public:
	Controller(QObject* parent = nullptr) : QObject(parent) {
   
		workThd = new WorkerThd(this);
		connect(this, &Controller::sigDoOtherWork, workThd, &WorkerThd::doOtherWork);
		connect(workThd, &QThread::finished, workThd, &QObject::deleteLater);
		workThd->start();
	}
	~Controller() {
   
		w
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值