线程是什么

学完 C/C++ 语言的读者,如果想深耕自己的技术栈,多线程编程是每个程序员必须掌握的技术,继续学习多线程编程是非常不错的选择。

自上世纪 90 年代末,CPU 开始朝着多核的方向发展,也就是给 CPU 安装多个核心(内核),每个核心都能独立地执行计算机指令。在任意时刻,单核 CPU 只能处理一个任务(如下图 a)所示),而多核 CPU 可以同时处理多个任务(如下图 b) 所示),大幅提升程序的执行效率。


图 1 CPU单核 VS 多核

现如今,常见的计算机比如电脑、手机、平板等,CPU 都是多核的,比如 4 核、8 核、12 核甚至更多,多核 CPU 已经成为计算机的标配。

大家先前编写的 C/C++ 程序,任意时刻只能执行一条指令,整个运行过程中也只能利用 CPU 的一个核心,多核 CPU 的优势根本发挥不出来。通过学习多线程编程技术,大家可以编写出“同时执行多个任务”的程序,充分利用 CPU 的多核优势,让程序的执行效率得到质的提升。

什么是线程

学习多线程编程,首先要搞清楚什么是线程。

关于这个问题,很多教程都给出了答案,比如说:
  • 线程是操作系统能够进行运算调度的最小单位,它被包含在进程中,是进程的实际运作单位;
  • 线程是进程中的⼀个执⾏单元,负责当前进程中程序的执⾏,⼀个进程中⾄少有⼀个线程;
  • 在计算机专用术语中,线程是指机器中连续的、顺序的属性集合。一个线程包含执行一系列机器指令所必须的机器状态,包括当前指令位置、地址和数据寄存器等。

它们的说法完全正确,而且非常严谨,从不同的角度诠释了线程的含义。但是,初学者真心看不懂,他们用板砖拍自己脑门也想不明白,线程究竟是个什么玩意,典型的只说“官话”不说“人话”。

线程和进程的关系非常密切,要想搞清楚线程是什么,必须先对进程有所了解。

进程(Process)

大家经常使用的操作系统,比如 Windows、Linux、Mac OS X、Android 和 iOS 等,它们都属于多任务操作系统,即可以同时运行多个程序。

以 Windows 为例,它支持同时运行 QQ、微信、迅雷、网易云音乐等多个应用程序,所以 Windows 是一款支持多任务的操作系统。

在多任务操作系统中,对于同时执行的多个程序,操作系统负责给它们分配执行所需要的全部资源(CPU、内存、I/O 设备等),还负责在适当的时机(比如程序执行结束后)回收这些资源。

为了让操作系统高效地管理(分配和回收)计算机资源,人们提出了“进程”的概念。

当一个程序执行时,操作系统负责分配所需要的全部资源,包括程序代码、数据、CPU、内存、I/O 设备等,这些资源就会组织成为一个进程。也就是说,程序执行时,操作系统会创建进程给它分配资源;程序执行结束后,操作系统会销毁进程回收资源。通过创建和销毁进程,操作系统就实现了对计算机资源的高效管理。

计算机中执行着多少个程序,就存在多少个进程,进程和正在执行的程序之间是一一对应的关系,所以我们习惯用进程代表正在执行的程序,经常会说:进程就是正在执行的程序。

对于系统中存在的多个进程,每个进程都拥有自己的内存空间和系统资源,它们之间相对独立,执行过程中不会互相干扰。

总结一下,进程包含程序执行所需要的全部计算机资源,包括程序代码、数据、CPU、内存、I/O 设备等。操作系统以进程为单位管理(分配和回收)计算机资源,也就是很多教材中讲的“进程是操作系统进行资源分配和调度的基本单位”。

注意,程序和进程是两个不同的概念。未执行的程序只是一段代码,通常以文件的形式存储在硬盘中,不占用系统资源(CPU、内存、I/O 设备等);进程指的是正在执行的程序,会占用系统资源,由操作系统负责管理。

线程(Thread)

读到这里,大家已经对进程有了大致的了解。线程和进程的联系非常紧密,接下来通过对比进程和线程,带大家理解线程的含义。

我们知道,每个正在执行的应用程序都是一个进程。重新观察图 1,一个完整的程序可能由多个任务组成,有些任务是可以独立执行的(和其它任务同时执行,如图 1b) 所示),每个独立执行的任务都是一个线程。

也就是说,线程是进程的一部分,进程和线程的关系如下图所示:


图 2 进程和线程的关系和区别

一个进程可以包含多个线程,它们可以共享进程的内存空间和一些系统资源,包括程序代码、数据(全局变量、静态变量、堆内存)、打开的文件资源、网络连接等。当然,各个线程也有一些私有的资源,比如程序计数器、栈内存、寄存器等。

一个进程至少要包含 1 个线程,原因很简单,进程只是操作系统为了方便管理计算机资源才创建的,真正负责执行程序的是线程,而不是进程。

当进程中只有一个线程时,所有的程序代码全部由该线程负责执行,这样的程序叫做单线程程序;当进程中包含多个线程时,每个线程分别负责执行一个任务,这样的程序叫做多线程程序。

单线程程序和多线程程序各有优缺点。单线程程序编写简单、易于调试,缺点是只能顺序执行程序,适用于简单的应用场景;多线程程序可以同时执行多个任务,执行效率高,但编写和调试过程比较复杂,容易出现数据竞争、死锁等问题,适用于复杂的应用场景。

举例讲解进程和线程的关系

如果把进程看做是一间工厂,那么线程就是工厂里的一条条生产线,如下图所示:


图 3 把进程比作工厂,把线程比作生产线

工厂可以包含很多条生产线,至少也要包含一条生产线。真正负责生产商品的是生产线,而不是工厂。

同属一家工厂的所有生产线,可以共享工厂的一些资源,比如工作场地、技术图纸、原材料、食堂等。每条生产线也有自己的私有资源,比如机器设备、生产记录,私人物品存储柜等。

总结

进程可以是使操作系统更高效地管理计算机资源。当程序执行时,操作系统会创建一个进程,进程包含程序执行所需要的全部资源(CPU、内存、I/O 设备等);当程序执行结束后,对应的进程会被操作系统销毁,占用的资源也会被操作系统回收。

线程是进程的一部分,一个进程可以包含多个线程,但至少要包含一个线程。真正负责执行程序的,是线程,而不是进程。

现如今,很多应用程序(软件)都是多线程程序,例如 QQ 支持同时和多个好友聊天、迅雷可以同时下载多个资源、大部分杀毒软件可以同时开启杀毒、清理垃圾、电脑加速等功能。

了解了什么是线程和多线程之后,接下来系统地讲解多线程编程,教大学编写多线程程序。

关  闭