关于进程与线程的简单理解(以工厂举例:cup-》工厂,车间-》进程,线程-》工人),可以参考阮一峰的博文进程与线程的一个简单图文解释。
先来了解下进程和线程的概念
关于多进程和多线程,教科书上最经典的一句话是“进程是资源分配的最小单位,线程是CPU调度的最小单位”。
进程
进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。
线程
线程(Thread)是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。就绪状态是指线程具备运行的所有条件,逻辑上可以运行,在等待处理机;运行状态是指线程占有处理机正在运行;阻塞状态是指线程在等待一个事件(如某个信号量),逻辑上不可执行。每一个程序都至少有一个线程,若程序只有一个线程,那就是程序本身。
线程是程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位指运行中的程序的调度单位。在单个程序中同时运行多个线程完成不同的工作,称为多线程。
进程和线程区别
进程是资源分配的基本单位。所有与该进程有关的资源,都被记录在进程控制块PCB中。以表示该进程拥有这些资源或正在使用它们。
另外,进程也是抢占处理机的调度单位,它拥有一个完整的虚拟地址空间。当进程发生调度时,不同的进程拥有不同的虚拟地址空间,而同一进程内的不同线程共享同一地址空间。
与进程相对应,线程与资源分配无关,它属于某一个进程,并与进程内的其他线程一起共享进程的资源。
线程只由相关堆栈(系统栈或用户栈)寄存器和线程控制表TCB组成。寄存器可被用来存储线程内的局部变量,但不能存储其他线程的相关变量。
通常在一个进程中可以包含若干个线程,它们可以利用进程所拥有的资源。在引入线程的操作系统中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位。由于线程比进程更小,基本上不拥有系统资源,故对它的调度所付出的开销就会小得多,能更高效的提高系统内多个程序间并发执行的程度,从而显著提高系统资源的利用率和吞吐量。因而近年来推出的通用操作系统都引入了线程,以便进一步提高系统的并发性,并把它视为现代操作系统的一个重要指标。
线程与进程的区别可以归纳为以下4点:
- 地址空间和其它资源(如打开文件):进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见。
- 通信:进程间通信IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信——需要进程同步和互斥手段的辅助,以保证数据的一致性。
- 调度和切换:线程上下文切换比进程上下文切换要快得多。
- 在多线程OS中,进程不是一个可执行的实体。
多进程和多线程的比较
进程的三种基本状态
(1)运行态(running)
当进程得到处理机,其执行程序正在处理机上运行时的状态称为运行状态。
在单CPU系统中,任何时刻最多只有一个进程处于运行状态。在多CPU系统中,处于运行状态的进程数最多为处理机的数目。
(2)就绪状态(ready)
当一个进程已经准备就绪,一旦得到CPU,就可立即运行,这时进程所处的状态称为就绪状态。系统中有一个就绪进程队列,处于就绪状态进程按某种调度策略存在于该队列中。
(3)等待态(阻塞态)(Wait / Blocked )
若一个进程正等待着某一事件发生(如等待输入输出操作的完成)而暂时停止执行的状态称为等待状态。处于等待状态的进程不具备运行的条件,即使给它CPU,也无法执行。系统中有几个等待进程队列(按等待的事件组成相应的等待队列)。
进程的控制和管理
进程是有生命周期的:产生、运行、暂停、终止。进程生命周期的动态变化过程由进程管理程序来控制。
进程的控制和管理包括:进程创建,进程撤消,进程阻塞,进程唤醒,进程挂起,进程激活
这些控制和管理功能由操作系统中的原语实现。原语是在核心态执行、完成系统特定功能的不可分割的过程。
原语的特点是执行过程中不允许被中断,是一个不可分割的基本单位,原语的执行是顺序的而不可能是并发的。
多线程的实现分为三类:
用户级线程(User Level Thread,ULT):对于这种线程的创建、撤消、和切换,由用户程序来实现,内核并不知道用户级线程的存在。
内核级线程(Kernel Level Thread ,KLT):它们是依赖于内核的,即无论是用户进程中的线程,还是系统进程中的线程,它们的创建、撤消、切换都由内核实现。
混合式线程:同时支持ULT和KLT两种线程。
1.用户级线程(ULT)
由应用程序完成所有线程的管理,通过用户空间中的线程库来完成,内核并不知道线程的存在。
优点:线程切换不调用核心,调度是应用程序特定的:可以按需要选择好的算法,ULT可运行在任何操作系统上(只需要线程库),可以在一个不支持线程的OS上实现。
缺点:由于大多数系统调用是阻塞的,因此一个用户级线程的阻塞会引起整个进程的阻塞。核心只将处理器分配给进程,同一进程中的两个线程不能同时运行于两个处理器上。
2.核心级线程(KLT)
所有线程管理由核心完成,没有线程库,但核心提供线程API来使用线程,核心维护进程和线程的上下文,线程之间的切换需要核心支持,以线程为基础进行调度。
优点:对多处理器,核心可以同时调度同一进程的多个线程,阻塞是在线程一级完成。
缺点:在同一进程内的线程切换调用内核,系统开销较大。
3.混合式线程
既支持用户级线程,又支持内核级线程。