不久之前,计算机程序还被设计和构建成一个接一个地运行的一系列指令。实际上,这种方法非常容易理解且易于实现,即便在今天,我们也使用相同的方法来编写以串行方式处理所需任务的脚本和简单的应用程序。然而,随着时间的推移,尤其是随着更强大处理器的出现,多任务处理问题日益凸显出来。人们希望计算机能够一次执行多个任务,这是因为计算机运行速度快,能够执行多个程序的指令,并且仍有一些空闲时间。当然,随着时间的推移,人们编写了更为复杂的应用程序(如游戏、图形程序等),此时需要处理器公平地管理不同程序所占用的时间片,以便所有程序都能正确运行。程序(或进程,在该环境中使用这个词更合适)被分割成更小的碎片,称为线程。这种方法(或称为多线程)到目前为止已经帮助人们创建了响应性更好、速度更快的进程,这样的进程能够与类似或完全不相关的进程一起运行,从而流畅地完成多任务处理任务。
在单处理器(且单核)计算机上,每个线程都被分配了一个时间片,而且很明显,处理器一次只能处理一个线程,但是通常多个线程之间可以快速地切换,因此,在用户看来,这种方式看起来像是真正的并行运行。然而,现在人们随身携带的大部分智能手机里的处理器都有能力使用处理器中的多个内核来处理多个线程。
定义为保证我们对线程及其用法有一个清晰的认识,并深入理解为什么必须使用线程才能编写强大的计算机视觉程序,下面请看进程与线程的主要区别:
① 什么是进程(Process)?
进程(Process)是计算机中的程序关于某数据集合上的一次运行,是操作系统进行资源分配和调度的基本单位。
② 什么是线程(Thread)?
线程(Thread)它被包含在进程之中,是操作系统能够进行执行的最小单位,是进程中的实际执行单位。
可能大多数人,对进程和线程还是不太熟悉,我们用下图进行阐述,我们把进程比作工厂,线程好比工厂的生产线,如果工厂只有一条流水线,那么我们就称为单线程。如果有多条流水线,就称为多线程。
通过以上了解,我们可以类比一下进程和线程的关系:在Qt和GUI编程中,一个这方面的典型例子是进度信息。运行一个复杂且耗时的进程时,通常需要显示一些有关进度的阶段以及状态信息,如剩余工作的百分比、完成所需的剩余时间等。最好将实际任务和GUI更新任务分解到不同的线程中。
线程状态我们知道线程处于进程之中,线程当被建立后处于就绪状态(Runnable),当CPU将时间片分给线程时,线程处于运行状态(Running)。当线程遇到阻塞的情况是,比如等待用户输入一个数据,线程就会处于阻塞状态(Blocked)。当线程处于阻塞状态时,CPU会调度其他的线程。
Qt 框架为处理应用程序中的多线程问题提供了各种不同的技术。正如将在后续文档中看到的, QThread 类用于处理各种多线程功能, QThread 类也是 Qt 框架中用于处理线程的最为强大且灵活的方式。除了 QThread 之外, Qt 框架还提供了很多其他的命名空间、类和函数,它们可以帮助处理各种多线程需求。在学习它们的用法之前,先来看看它们的列表: