Qt框架QThread类线程基础知识

北京中科白癜风医院正规的吗 https://news.360xh.com/202003/18/56218.html

什么是线程?

线程是并行执行操作,就像进程一样。那么,线程与进程有何不同呢?在电子表格上进行计算时,可能还有一个媒体播放器在同一桌面上播放您最喜爱的歌曲。下面是两个并行工作的过程的示例:一个运行电子表格程序;一个运行媒体播放器。多任务处理是一个众所周知的术语。仔细观察媒体播放器后发现,在一个进程中,又发生了一些平行的事情。当媒体播放器向音频驱动程序发送音乐时,其所有铃声和口哨的用户界面都在不断更新。这就是线程的用——在单个进程中并发。

那么,如何实现并发呢?单核CPU的并行工作是一种错觉,与在影院中移动图像的错觉有些相似。对于进程,在很短的时间后中断处理器在一个进程上的工作,产生错觉。然后处理器继续进入下一个进程。为了在进程之间切换,将保存当前程序计数器并加载下一个处理器的程序计数器。这是不够的,因为同样需要完成对寄存器和某些体系结构和操作系统特定的数据。

PythonGUI设计PyQt5从入门到实践(全彩版)赠纸质专属魔卡、PPT课件京东月销量旗舰店¥79.56购买

正如一个CPU可以为两个或多个进程供电一样,也可以让CPU在单个进程的两个不同的代码段上运行。当进程启动时,它始终执行一个代码段,因此该进程据说有一个线程。但是,程序可能决定启动第二个线程。然后,在一个进程中同时处理两个不同的代码序列。通过重复保存程序计数器和寄存器,然后加载下一个线程的程序计数器和寄存器,在单个核心CPU上实现并发。无需程序合作,无需在活动线程之间循环。当切换到下一个线程时,线程可能处于任何状态。

CPU设计中的当前趋势是有几个内核。典型的单线程应用程序只能使用一个内核。但是,具有多个线程的程序可以分配给多个内核,使事情以真正并发的方式发生。因此,将工作分发到多个线程可以使程序在多核CPU上运行得更快,因为可以使用其他内核。

GUI线程和辅助线程

如前所述,每个程序在启动时都有一个线程。此线程称为主线程(在Qt应用程序中也称为GUI线程)。QtGUI必须在此线程中运行。所有小部件和几个相关类(例如QPixmap)在辅助线程中不起作用。辅助线程通常称为辅助线程,因为它用于从主线程卸载处理工作。

QtQuick核心编程安晓辉编京东¥.5购买已下架

同时访问数据

每个线程都有自己的堆栈,这意味着每个线程都有自己的调用历史记录和局部变量。与进程不同,线程共享相同的地址空间。下图显示了线程的构建基块在内存中的定位。非活动线程的程序计数器和寄存器通常保存在内核空间中。代码有一个共享副本,每个线程都有一个单独的堆栈。

如果两个线程具有指向同一对象的指针,则两个线程可能同时访问该对象,这可能会破坏该对象的完整性。当同时执行同一对象的两种方法时,很容易想象会出错的很多事情。

有时需要从不同的线程访问一个对象;例如,当生活在不同线程中的对象需要通信时。由于线程使用相同的地址空间,因此线程交换数据比进程更容易、更快。数据不必序列化和复制。传递指针是可能的,但必须严格协调哪个线程接触哪个对象。必须防止同时对一个对象执行操作。有几种方法可以实现这一目标,其中一些方法如下所述。

那么,可以安全地做什么呢?在线程中创建的所有对象都可以在该线程内安全地使用,前提是其他线程没有对它们的引用,并且对象没有与其他线程的隐式耦合。当数据在实例之间共享(如静态成员、单例或全局数据)时,可能会发生这种隐式耦合。熟悉线程安全和重入类和函数的概念。

Qt5.9C++开发指南QT编程教程C++编程书Qt5.9LTS版本为开发平台QtC京东查看已下架

使用线程

线程基本上有两个用例:

利用多核处理器加快处理速度。通过卸载长期处理或阻止对其他线程的调用,保持GUI线程或其他时间关键线程的响应。何时使用线程的替代方法

开发人员需要非常小心线程。启动其他线程很容易,但很难确保所有共享数据保持一致。问题通常很难找到,因为它们可能只偶尔出现一次,或者只出现在特定的硬件配置上。在创建线程来解决某些问题之前,应考虑可能的替代方案。

通常,建议仅使用安全和测试的路径,并避免引入临时线程概念。QtConcurrs模块提供了一个简单的接口,用于将工作分发到处理器的所有内核。线程代码完全隐藏在QtConcurron框架中,因此您不必处理详细信息。但是,当需要与正在运行的线程通信时,不能使用QtConcurrs,并且不应用于处理阻塞操作。

Qt5/PyQt5实战指南:手把手教你掌握个精彩案例京东¥.6购买

您应该使用哪种Qt线程技术?

有关Qt多线程的不同方法的介绍,请参阅Qt页的多线程技术,以及有关如何在其中选择的方法的指南。

Qt线程基础知识

以下各节介绍QObjects如何与线程交互,程序如何安全地访问来自多个线程的数据,以及异步执行如何在不阻塞线程的情况下生成结果。

Qt对象和线程

如上所述,开发人员在从其他线程调用对象的方法时必须始终小心谨慎。线程相关性不会更改这种情况。Qt文档将几种方法标记为线程安全。postEvent()是一个值得注意的例子。可以同时从不同的线程调用线程安全方法。

在通常没有对方法的并发访问的情况下,在其他线程中调用非线程安全的对象方法可能在并发访问发生之前工作数千次,从而导致意外行为。编写测试代码并不完全确保线程正确性,但它仍然很重要。在Linux上,Valgrind和Helgrind可以帮助检测线程错误。

保护数据的完整性

编写多线程应用程序时,必须格外小心以避免数据损坏。有关如何安全地使用线程的讨论,请参阅同步线程。

Qt5.12实战京东好评率94%无理由退换京东配送官方店旗舰店¥83.3购买

处理异步执行

获取辅助线程结果的一个方法就是等待线程终止。但是,在许多情况下,阻止等待是不能接受的。阻塞等待的替代方法是异步结果交付,具有已过帐的事件或排队信号和插槽。这会产生一定的开销,因为操作的结果不会出现在下一个源行上,而是显示在位于源文件中其他位置的插槽中。Qt开发人员习惯于使用这种异步行为,因为它与GUI应用程序中使用的事件驱动编程类型非常相似。

例子

#Qt#附带了几个使用线程的示例。有关简单示例,请参阅QThread和QThreadPool的类引用。有关更高级的示例,请参阅线程和并发编程示例页面。

深入挖掘

线程是一个非常复杂的主题。Qt提供的线程类比我们在本教程中介绍的要多。以下材料可以帮助您更深入地了解主题:

支持是参考文档中的一个很好的起点。Qt附带了几个额外的示例。几本好书描述了如何使用Qt线程。最广泛的报道可以在马克·萨默菲尔德,普伦蒂斯大厅的高级Qt编程找到-大约70的页覆盖。使用Qt框架实现基于QPainter类的自定义场景图

Qt创建基于Widget小部件的应用程序

Qt6对Concurrent并发模块的更新

C++Qt框架Concurrent并发模块使用方法

Qt框架流布局QFlowlayout使用实例




转载请注明:http://www.aierlanlan.com/rzgz/1616.html