进程和线程的相关内容,探究起来比较复杂,这里就先了解和记录下一些比较基础的概念和相关知识,等以后学习Linux内核相关的代码时再详细记录吧。
什么是进程
进程,是可并发执行的程序在一个数据集上的一次执行过程,它是系统资源分配的基本单位。从结构上看,进程实体是由 程序段、数据段和进程控制块(PCB)
三部分组成,这三部分也被统称为”进程映像”或”进程上下文”。
进程状态
在一个进程的活动期间,它至少具备三种基本状态:就绪状态
、执行状态
、等待状态
。
进程控制块
每一个进程有且只有一个进程控制块(Process Control Block, PCB),进程控制块是操作系统用于记录和描述进程状态及相关信息的数据结构,也是操作系统控制和管理进程的主要依据。PCB是进程存在的唯一标志。操作系统的并发执行也是根据PCB来进行控制和管理的。
进程队列
通常把处于相同状态的进程链接在一起,称为”进程队列”。比如若干个等待执行的进程(就绪进程)按一定的次序链接起来的队列称为”就绪队列”。把等待资源或等待某些时间的进程也排成队列,称为”等待队列”。
链接方式:单向链接和双向链接,如下图。
索引方式:
进程调度
在多道程序设计的系统中,往往有多个进程处于就绪状态,它们都要求占用CPU执行。但是,一个处理器每一时刻只能让一个进程占用。所以操作系统设计了一个“进程调度”来解决竞争CPU的问题。
进程调度的主要功能有:
- 记录系统中所有进程的执行情况;
- 选择占有CPU的进程;
- 把CPU分配给进程,并进行进程上下文切换;
- 收回CPU;
进程调度的时机:
- 正在执行的进程执行完毕;
- 执行中的进程被阻塞;
- 在分时系统中时间片用完;
- 在执行完系统调用等系统程序返回用户进程时;
- 执行中的进程被优先级更高的进程剥夺CPU;
进程调度算法:
- 先来先服务算法(FCFS)
- 优先数调度算法
- 时间片轮转调度算法
- 多级反馈队列调度算法
什么是线程
线程(Thread),是进程中的一个实体,是CPU调度的基本单位。一个进程可以有一个或多个线程,它们共享所属进程所拥有的资源。线程具有一下特性:
- 多个线程可以并发执行;
- 一个线程可以创建另一个线程;
- 线程具有动态性。一个线程被创建之后便开始了它的生命周期,期间可能处于不同的状态,直至死亡;
- 每个线程具有自己的线程控制块(Thread Controlling Block, TCB),其中记录了该线程的标识符、线程执行时的寄存器和栈等现场状态信息;
- 在同一个进程内,各线程共享同一地址空间(即所属进程的存储空间);
- 一个进程中的线程在另一个进程中是不可见的;
- 同一个进程内的线程间的通信主要是基于全局变量进行的;
线程的分类
多线程的实现分为三类:内核级线程
(Kernel Level Thread, KLT)、用户级线程
(User Level Thread, ULT)、混合式线程
,即同时支持ULT和KLT两种线程。
进程与线程结构
引入线程后,一个进程可包括一个或多个线程。如果一个进程只包括一个线程,则该进程除了有自己的PCB、拥有的存储空间、栈(每个进程会有两个栈,一个用户栈,存在于用户空间,一个内核栈,存在于内核空间。当进程在用户空间运行时,cpu堆栈指针寄存器里面的内容是用户堆栈地址,使用用户栈;当进程在内核空间时,cpu堆栈指针寄存器里面的内容是内核栈空间地址,使用内核栈)以外,还有对应的TCB。如下图所示。
而如果一个进程包含了多个线程,该进程也包括自己的PCB、存储空间、栈以及各个线程的TCB,但是每个线程将拥有自己的栈,这些栈都数据该进程的栈。如下图。