20-第五章 Qt程序设计4-多线程_第1页
20-第五章 Qt程序设计4-多线程_第2页
20-第五章 Qt程序设计4-多线程_第3页
20-第五章 Qt程序设计4-多线程_第4页
20-第五章 Qt程序设计4-多线程_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

——基于Qt(Windows)版医用仪器软件设计MedicalInstrumentSoftwareDesign2022第5章Qt程序设计3-——BasedonQt(WindowsEdition)多线程关于这节课Aboutthiscourse.“One

在Qt程序设计的过程中,有4个非常重要的概念需要熟练掌握,分别为布局管理器,信号与槽,模态、半模态和非模态对话框,以及多线程,本章将详细介绍这4个概念。目录实验内容实验原理实验步骤本节任务实验内容

为了满足用户构造复杂图形界面系统的需求,Qt提供了丰富的多线程编程支持。本节将介绍多线程的优点和创建方法,然后介绍线程同步的概念,最后通过实验设计一个多线程的程序。实验原理

一个应用程序通常只有一个线程,称为主线程。线程内的操作是按顺序执行的,如果在主线程中执行一些耗时的操作(如加载图片、大型文件读取、文件传输和密集计算等),就会阻塞主线程,从而导致用户界面失去响应。在这种情况下,单一线程就无法适应应用程序的需求。可以再创建一个单独的线程,将耗时的操作转移到新建的线程中执行,并处理好该线程与主线程之间的同步与数据交互即可避免上述问题,这就是多线程应用程序。1.什么是多线程线程A线程B任务1任务2任务3任务4任务52.多线程的特点相比于单线程,多线程具有以下特点。(1)可提高应用程序的响应速度。在多线程下,可将一些耗时的操作置于一个单独的线程,使用户界面一直处于活动状态,避免因主线程阻塞而失去响应。(2)可提高多处理器系统的CPU利用率。当线程数小于CPU数目时,操作系统会合理分配各个线程使其分别在不同的CPU上运行。(3)改善程序结构。可将一些代码量庞大的复杂线程分为多个独立或半独立的执行部分,既可以增加代码的可读性,也有利于代码的维护。(4)可以分别设置各个任务的优先级以优化性能。(5)等候使用共享资源时会造成程序的运行速度变慢。这些共享资源主要是独占性的资源,如打印机等。(6)管理多个线程需要额外的CPU开销。多线程的使用会给系统带来上下文切换的额外负担(上下文切换是指内核在CPU上对进程或线程进行切换)。(7)容易造成线程的死锁。(8)同时读写公有变量容易造成脏读(读出无效数据)。3.如何使用多线程

Qt提供了对多线程操作的支持,包括一套独立于平台的线程类库、一个线程安全的事件发送途径,及可跨线程使用的信号与槽。此外,还提供了用于线程之间通信与同步的若干机制,使得基于Qt的多线程应用程序开发变得灵活简单。

Qt中的QThread类提供了管理线程的方法,是实现多线程的核心类。一个QThread类的对象管理一个线程,该线程可以与应用程序中的其他线程分享数据,但是是独立运行的。

创建一个新线程的方法为:自定义一个继承自QThread的类,并重写run()方法,在run()方法中添加该线程需要完成的任务,然后在主线程中创建一个上述自定义类的对象并实例化,最后调用QThread::start()方法开始新线程。

相比于一般的程序都是从main()函数开始执行的,QThread是从run()方法开始执行的,start()方法默认调用run()方法。QThread会在线程启动、结束和终止时分别发出started()、finished()和terminated()信号。可以用isRunning()和isFinished()来查询线程的状态,还可以使用wait()来阻塞线程,直到线程结束。run()通过调用exec()方法来开启事件循环,并在线程内运行一个Qt事件循环,可以使用quit()退出事件循环。当从run()方法返回后,线程便执行结束。应用程序主程序fun1()fun2()…子程序继承QThreadrun()4.线程同步

线程同步主要是为了协调各个线程之间的工作,以便更好地完成一些任务。虽然多线程的思想是多个线程尽可能多地并发执行,但有时候有些线程需要暂停等待其他线程,如两个线程同时访问同一个全局变量,如果没有线程同步,读出的结果通常是不确定的。

Qt中提供了丰富的类用于进行线程同步,常用的有QMutex、QReadWriteLock、QSemaphore和QWaitCondition。(1)QMutex

QMutex是基于互斥量的线程同步类,可以确保多个线程对同一资源的顺序访问。使用QMutex定义一个互斥量mutex,通过mutex.lock()和mutex.unlock()分别锁定和解锁互斥量,则处于mutex.lock()和mutex.unlock()之间的代码为保护状态,同一时间最多只能有一个线程访问此段代码。当一个线程锁定互斥量后,若另一个线程也尝试调用lock()来锁定这个互斥量,则不但无法成功锁定,反而会阻塞执行直到前一个线程解锁互斥量。通过调用tryLock()方法也可以锁定互斥量,但与lock()不同的是,如果成功锁定就返回true;如果其他线程已经锁定这个互斥量则返回false,但不会阻塞线程执行。(1)QMutex

QMutex是基于互斥量的线程同步类,可以确保多个线程对同一资源的顺序访问。使用QMutex定义一个互斥量mutex,通过mutex.lock()和mutex.unlock()分别锁定和解锁互斥量,则处于mutex.lock()和mutex.unlock()之间的代码为保护状态,同一时间最多只能有一个线程访问此段代码。当一个线程锁定互斥量后,若另一个线程也尝试调用lock()来锁定这个互斥量,则不但无法成功锁定,反而会阻塞执行直到前一个线程解锁互斥量。通过调用tryLock()方法也可以锁定互斥量,但与lock()不同的是,如果成功锁定就返回true;如果其他线程已经锁定这个互斥量则返回false,但不会阻塞线程执行。例:同时在两个线程分别调用方法1,方法2方法1方法2输出结果:ABCABCDEFDEF输出结果:ABCDEFABCDEF(2)QReadWriteRead

使用互斥量在提升线程安全性的同时也有弊端:若程序中有多个线程仅需读取某一公有变量,如果使用互斥量则必须排队访问,这样就会降低程序的性能,使用QReadWriteRead类可以避免上述问题。QReadWriteRead以读锁定或写锁定的方式保护一段代码,允许多个线程以只读的形式访问公有资源。常用方法有lockForRead()、lockForWrite()、unlock()、tryLockForRead()和tryLockForWrite()。例:右图为Qt读写锁的演示及验证,在下图中可以看出两个读取数据的函数会一起调用(代表读写锁支持读取锁线程一起运行),且数据操函数并不会调用;而当数据操作函数调用时,两个数据读取函数也不会调用。由此可知,当读取锁开启时,写入锁不能进入,反之亦然。(3)QSemaphore

QSemaphore为基于信号量的线程同步类,即对互斥量功能的扩展。使用互斥量只能保护一个资源,信号量可以保护多个资源。QSemaphore的构造方法可以指定一个参数,即为当前可用资源的个数,默认为0。QSemaphore提供了acquire()和release()方法来获取和释放资源。(4)QWaitCondition

QWaitCondition允许一个线程在满足特定条件后,通知或唤醒其他多个线程。唤醒方式是通过wakeOne()和wakeAll()方法,前者唤醒一个处于等待状态的线程,后者唤醒所有处

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论