[Qt][Qt 多线程][下]详细讲解


1.QThread 常用的函数

  • exec():进⼊事件循环并等待exit()被调⽤,返回传递给exit()的值
    • 如果通过quit()调⽤exit(), 返回值为0
    • 这个函数应该在run()中调⽤,必须调⽤此函数来启动事件处理
  • exit():告诉线程的事件循环退出并返回代码
  • currentThread():返回⼀个指向管理当前执⾏线程的QThread的指针
  • idealThreadCount():返回可在系统上运⾏的理想线程数
    • 这是通过查询系统中实际的和逻辑的处理器内核的数量来完成的
    • 如果⽆法检测到处理器核数,则此函数返回1
  • isRunning():如果线程正在运⾏则返回true,否则返回false
  • msleep():强制当前线程休眠,单位为毫秒
  • sleep():强制当前线程休眠数秒
    • 此函数不保证准确性,在重载条件下,应⽤程序的休眠时间可能超过⼏秒
  • usleep():强制当前线程休眠数秒(微秒)
    • 此函数不保证准确性,在重载条件下,应⽤程序的休眠时间可能超过⼏秒
  • requestInterruption()请求线程的中断
    • 该请求是咨询性的,由线程上运⾏的代码决定是否以及如何对此类请求采取⾏动
    • 此函数不会停⽌线程上运⾏的任何事件循环,也不会以任何⽅式终⽌线程
  • run()线程的起点,调⽤start()后,新创建的线程调⽤此函数
  • quit():告诉线程的事件循环以返回码0(success)退出,相当于调⽤QThread::exit(0)
  • wait():阻塞线程,直到满⾜以下任何⼀个条件:
    • 与此QThread对象关联的线程已经完成执⾏(即当它从run()返回时)
      • 如果线程已经完成,这个函数将返回true
      • 如果线程尚未启动,它也返回true
    • 已经过了⼏毫秒
      • 如果时间是ULONG_MAX(默认值),那么等待永远不会超时(线程必须从run()返回)
      • 如果等待超时,此函数将返回false
    • 这提供了与POSIX pthread_join()函数类似的功能
  • start():通过调⽤run()开始执⾏线程,OS将根据优先级参数调度线程
    • 如果线程已经在运⾏,这个函数什么也不做
  • terminate():终⽌线程的执⾏
    • 线程可以⽴即终⽌,也可以不⽴即终⽌,这取决于OS的调度策略
    • terminate()之后使⽤QThread::wait()来确保
  • finished()当线程结束时会发出该信号,可以通过该信号来实现线程的清理⼯作

2.线程同步工具

0.简介

  • 线程并⾏会导致资源竞争,线程同步⼯具会解决这些冲突
  • 实现线程互斥和同步常⽤的类有:
    • 互斥锁QMutexQMutexLocker
    • 条件变量QWaitCondition
    • 信号量QSemaphore
    • 读写锁QReadLockerQWriteLockerQReadWriteLock

1.互斥锁

  • 互斥锁是⼀种保护和防⽌多个线程同时访问同⼀对象实例的⽅法
    • 把多个线程要访问的公共资源,通过锁保护起来 --> 把并发执行变成串行执行
    • Qt中,互斥锁主要是通过QMutex类来处理
  • QMutex
    • 特点:⽤于保护共享资源的访问,实现线程间的互斥操作
    • ⽤途:在多线程环境下,通过互斥锁来控制对共享数据的访问,确保线程安全
    • 示例
      QMutex mutex;
      
      mutex.lock(); // 上锁
      // 访问共享资源
      mutex.unlock(); // 解锁
      
  • QMutexLocker
    • 特点QMutexLockerQMutex的辅助类,使⽤RAII⽅式对互斥锁进⾏上锁和解锁操作
    • ⽤途:简化对互斥锁的上锁和解锁操作,避免忘记解锁导致的死锁等问题
    • 示例
      QMutex mutex;
      {
      	QMutexLocker locker(mutex); // 在作用域内自动上锁
      	// 访问临界资源
      } // 出作用域自动解锁
      
  • QReadWriteLockerQReadLockerQWriteLocker
    • 特点
      • QReadWriteLock:读写锁类,⽤于控制读和写的并发访问
      • QReadLocker:⽤于读操作上锁,允许多个线程同时读取共享资源
      • QWriteLocker:⽤于写操作上锁,只允许⼀个线程写⼊共享资源
    • 用途:在某些情况下,多个线程可以同时读取共享数据,但只有⼀个线程能够进⾏写操作
      • 读写锁提供了更⾼效的并发访问⽅式
    • 示例
      QReadWriteLock rwLock;
      
      // 在读操作中使⽤读锁
      {
      	QReadLocker locker(&rwLock); // 在作⽤域内⾃动上读锁
      	// 读取共享资源
      }// 在作⽤域结束时⾃动解读锁
      
      // 在写操作中使⽤写锁
      {
      	QWriteLocker locker(&rwLock); // 在作⽤域内⾃动上写锁
      	// 修改共享资源
      }// 在作⽤域结束时⾃动解写锁
      

2.信号量

  • 有时在多线程编程中,需要确保多个线程可以相应的访问⼀个数量有限的相同资源
  • 信号量类似于增强的互斥锁,不仅能完成上锁和解锁操作,⽽且可以跟踪可⽤资源的数量
  • 特点QSemaphore是Qt框架提供的计数信号量类,⽤于控制同时访问共享资源的线程数量
  • ⽤途:限制并发线程数量,⽤于解决⼀些资源有限的问题
  • 示例
    QSemaphore semaphore(2); // 同时允许两个线程访问共享资源
    
    // 在需要访问共享资源的线程中
    semaphore.acquire(); // 尝试获取信号量,若已满则阻塞
    
    // 访问共享资源
    
    semaphore.release(); // 释放信号量
    
    // 在另⼀个线程中进⾏类似操作
    

3.条件变量

  • 在多线程编程中,假设除了等待OS正在执⾏的线程之外,某个线程还必须等待某些条件满⾜才能执⾏,这时就会出现问题
    • 这种情况下,线程会很⾃然地使⽤锁的机制来阻塞其他线程
    • 因为这只是线程的轮流使⽤,并且该线程等待某些特定条件
      • ⼈们会认为需要等待条件的线程,在释放互斥锁或读写锁之后进⼊了睡眠状态
      • 这样其他线程就可以继续运⾏,当条件满⾜时,等待条件的线程将被另⼀个线程唤醒
  • 在Qt中,专⻔提供了QWaitCondition类来解决上述这样的问题
    • 多个线程之间的调度是无序的,为了一定程度的干预线程之间的执行顺序,引入条件变量
  • 特点QWaitCondition是Qt框架提供的条件变量类,⽤于线程之间的消息通信和同步
  • ⽤途:在某个条件满⾜时等待或唤醒线程,⽤于线程的同步和协调
  • 示例
    QMutex mutex;
    QWaitCondition condition;
    ---------------------------------------------------------------
    // 在等待线程中
    mutex.lock();
    
    // 检查条件是否满⾜,若不满⾜则等待
    while (!conditionFullfilled())
    {
    	condition.wait(&mutex); // 等待条件满⾜并释放锁
    }
    
    // 条件满⾜后继续执⾏
    
    mutex.unlock();
    ---------------------------------------------------------------
    // 在改变条件的线程中
    mutex.lock();
    
    // 改变条件
    changeCondition();
    condition.wakeAll(); // 唤醒等待的线程
    
    mutex.unlock();
    
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DieSnowK

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值