并发无论是在操作系统层面还是在编程语言层面,都是一个极为重要的概念。线程(thread)是对并发的一种抽象,经典观念认为一个程序只有一个执行点(一个程序计数器,用来指向要执行的指令)。但是多线程(multi-thread)程序会有多个执行点(多个程序计数器)。换个角度来看,线程的概念类似于进程,有别于进程的地方就是多线程环境下,每个线程他们要共享地址空间,不同线程之间能够访问到共同的数据。
线程与进程十分相似,但又不同,进程是分时操作系统最早提出的一种任务调度模型。进程的出现使得操作系统拥有更好的交互性和更高的效率。在操作系统中,每个进程都有自己独立的地址空间,各个进程之间相互隔离,互补干扰。
而线程可以看做是更细粒度的一种进程。但是线程必须依赖于进程存在,没有独立于进程的线程。进程是操作系统分配资源的最小单位,线程是操作系统调度的最小单位。
现代分时操作系统中大部分操作系统都支持线程,线程成为了CPU,操作系统调度的最小单元。然而线程不仅仅局限于操作系统,线程这个抽象的概念也可以被程序设计语言去实现。所以按照线程的实现者的不同可以将线程分为两类:
- 用户线程:有程序设计语言实现(软件实现),不依赖于操作系统。
- 内核线程:操作系统实现,操作系统负责调度。
有关进程
进程:一个具有独立功能的程序在数据集合上的一次动态执行过程。(进程的学术定义)
进程这个概念与程序,或者我们的代码有很大的联系。我们写出的代码最终要变成计算机可以识别的二进制语言存储于内存中,进程可以看做是代码的一次动态执行。有人说,程序=数据结构+算法。这种说法完全正确,但也可以退化来看:程序=数据+指令。所以进程就可以看做是数据和指令在计算机内的一次运行。
所以进程与程序的关系大致如下:
- 程序是产生进程的基础。
- 程序每次运行构成了不同的进程。
- 进程是程序功能的体现。
- 一个程序可以对应多个进程,通过调用关系,一个进程又可以包括多个程序。
同时进程与程序的区别大致如下:
- 进程是一个动态的概念。程序是一个静态的概念。程序是有序指令的集合,进程是程序的一次执行。
- 进程具有一定的时效性,它的运行周期可预期。
所以进程可以看作是程序的实例,程序可以看作是进程的模板。
进程的组成
- code 代码
- data 数据
- PCB(Process Control Block) 进程控制块
进程的特点
- 动态性:进程可以被动态创建,也可以动态结束。
- 并发性:进程可以被独立调度,并占用处理机运行。
- 独立性:不同进程之间是相互隔离,互不影响的。
- 制约性:因访问共享资源(数据)或进程间同步而受到制约。
PCB的构成
- 进程标识信息
- 本进程标识
- 父进程标识
- 用户标识
- 处理器状态信息
- 用户可见寄存器
- 控制和状态寄存器:PC,PSW
- 栈指针
- 资源信息