进程与线程

目录

一.进程的概念

二.进程实体的组成

1.PCB(PCB是进程存在的唯一标志!)

2.程序段

3.数据段

三.进程的特征

1.动态性(动态性是进程最基本的特征)

2.并发性

3.独立性

4.异步性

5.结构性

四.进程的状态与转换

1.三种基本状态

2.另外两种状态

④创建状态

3.状态间的转换

就绪态->运行态

运行态->就绪态

运行态->阻塞态

阻塞态->就绪态

创建态->就绪态

运行态->终止态

五.进程的组织方式

1.链式

2.索引式

六.进程的控制

1.什么是进程控制?

2.用原语实现进程控制

3.进程控制相关原语

①进程的创建

创建原语

引起进程创建的事件

②进程的终止

撤销原语

引起进程终止的事件

③进程的阻塞

阻塞原语

引起进程阻塞的事件

④进程的唤醒

唤醒原语

引起进程唤醒的事件

⑤进程的切换

切换原语

引起进程切换的事件

七.进程的通信

1.共享存储

基于数据结构的共享

基于存储区的共享

2.消息传递

直接通信方式

间接通信方式

3.管道通信

八.线程的概念

1.什么是线程,为什么要引入线程?

2.引入线程带来的变化

3.线程的属性

九.线程的实现方式

1.用户级线程

2.内核级线程

十.多线程模型

1.一对一

2.多对一

3.多对多

十一.线程的状态与转换

十三.线程的组织与控制


一.进程的概念

进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位

一个程序的一次执行可以产生多个不同的进程,例如产生子进程;
一个程序的多次运行可形成多个不同的进程;
一个进程可以顺序地执行一个或者多个程序。

二.进程实体的组成

程序段、数据段、PCB三部分组成了进程实体(进程映像)引入进程实体的概念后,可把进程定义为:

进程是进程实体的运行过程,是系统进行资源分配和调度(一个进程被“调度”,就是指操作系统决定让这个进程上CPU运行)的一个独立单位。

一个进程实体(进程映像)由PCB、程序段、数据段组成。

程序段、数据段是给进程自己用的,与进程自身的运行逻辑有关

PCB 是给操作系统用的

进程是动态的,进程实体(进程映像)是静态的。

同时挂三个QQ号,会对应三个QQ进程,它们的PCB、数据段各不相同,但程序段的内容都是相同的(都是运行着相同的QQ程序)

1.PCB(PCB是进程存在的唯一标志!)

Linux0.11中的PCB的原码,其实就是一个数据结构: 

struct task_struct {
/* these are hardcoded - don't touch */
	long state;	/* -1 unrunnable, 0 runnable, >0 stopped */
	long counter;
	long priority;
	long signal;
	struct sigaction sigaction[32];
	long blocked;	/* bitmap of masked signals */
/* various fields */
	int exit_code;
	unsigned long start_code,end_code,end_data,brk,start_stack;
	long pid,father,pgrp,session,leader;
	unsigned short uid,euid,suid;
	unsigned short gid,egid,sgid;
	long alarm;
	long utime,stime,cutime,cstime,start_time;
	unsigned short used_math;
/* file system info */
	int tty;		/* -1 if no tty, so it must be signed */
	unsigned short umask;
	struct m_inode * pwd;
	struct m_inode * root;
	struct m_inode * executable;
	unsigned long close_on_exec;
	struct file * filp[NR_OPEN];
/* ldt for this task 0 - zero 1 - cs 2 - ds&ss */
	struct desc_struct ldt[3];
/* tss for this task */
	struct tss_struct tss;
};

进程描述信息

进程控制和管理信息

资源分配清单

处理机相关信息

进程标识符(PID)

进程当前状态

代码段指针

通用寄存器值

用户标识符(UID)

进程优先级

数据段指针

地址寄存器值

代码运行入口地址

堆栈段指针

控制寄存器值

程序的外存地址

文件描述符

标志寄存器值

进入内存时间

键盘

状态字

CPU 占用时间

鼠标

信号量使用

进程描述信息

进程标识符:标志各个进程,每个进程都有一个唯一的标识号。

用户标识符:进程所归属的用户,用户标识符主要为共享和保护服务。

进程控制和管理信息

进程当前状态:描述进程的状态信息,作为CPU分配调度的依据。

进程优先级:描述进程抢占CPU的优先级,优先级高的进程可优先获得CPU。

资源分配清单

用于说明有关内存地址空间或虚拟地址空间的状况,所打开文件的列表和所使用的输入/输出设备信息。

处理机相关信息

也称CPU的上下文,主要指CPU中各寄存器的值。当进程处于执行态时,CPU的许多信息都在寄存器中。当进程被切换时,CPU状态信息都必须保存在相应的 PCB 中,以便在该进程重新执行时,能从断点继续执行。

2.程序段

程序的代码(指令序列)

程序段就是能被进程调度程序调度到CPU执行的程序代码段。注意,程序可被多个进程共享,即多个进程可以运行同一个程序。

3.数据段

运行过程中产生的各种数据(如:程序中定义的变量)

一个进程的数据段,可以是进程对应的程序加工处理的原始数据,也可以是程序执行时产生的中间或最终结果。

三.进程的特征

1.动态性(动态性是进程最基本的特征)

进程是程序的一次执行过程,是动态地产生、变化和消亡的

2.并发性

内存中有多个进程实体,各进程可并发执行

3.独立性

进程是能独立运行、独立获得资源、独立接受调度的基本单位

4.异步性

各进程按各自独立的、不可预知的速度向前推进操作系统要提供“进程同步机制"来解决异步问题

5.结构性

每个进程都会配置一个PCB。结构上看,进程由程序段、数据段、PCB组成

四.进程的状态与转换

1.三种基本状态

进程的整个生命周期中,大部分时间都处于三种基本状态

CPU

其他所需资源

运行状态

就绪状态

阻塞状态

  • 运行状态

占有CPU,并在CPU上运行

  • 就绪状态

已经具备运行条件,但由于没有空闲CPU,而暂时不能运行

  • 阻塞状态

因等待某一事件而暂时不能运行

2.另外两种状态

④创建状态

进程正在被创建,操作系统为进程分配资源、初始化PCB

  • 终止状态

进程正在从系统中撤销,操作系统会回收进程拥有的资源、撤销PCB

3.状态间的转换

就绪态->运行态

进程被调度

运行态->就绪态

时间片到,或CPU被其他高优先级的进程抢占

运行态->阻塞态

等待系统资源分配,或等待某事件发生(主动行为)

阻塞态->就绪态

资源分配到位,等待的事件发生(被动行为)

创建态->就绪态

系统完成创建进程相关的工作

运行态->终止态

进程运行结束,或运行过程中遇到不可修复的错误

五.进程的组织方式

进程PCB中,会有一个变量 state 来表示进程的当前状态。如:1表示创建态、2表示就绪态、3表示运行态….

为了对同一个状态下的各个进程进行统一的管理,操作系统会将各个进程的PCB组织起来。

1.链式

按照进程状态将PCB分为多个队列

操作系统持有指向各个队列的指针

2.索引式

根据进程状态的不同,建立几张索引表

操作系统持有指向各个索引表的指针

六.进程的控制

1.什么是进程控制?

进程控制的主要功能是对系统中的所有进程实施有效的管理,它具有创建新进程、撤销已有进程、实现进程状态转换等功能。

说白了:反正进程控制就是要实现进程状态转换。

2.用原语实现进程控制

内核中一种特殊的程序,具有原子性,执行起来必须一气呵成,不可中断。

如果不能“一气呵成”,就有可能导致操作系统中的某些关键数据结构信息不统一的情况,这会影响操作系统进行别的管理工作

故此需要用“原语”来执行工作。

可以用“关中断指令”和“开中断指令”这两个特权指令实现原子性:

CPU执行了关中断指令之后,就不再例行检查中断信号,直到执行开中断指令之后才会恢复检查

这样,关中断、开中断之间的这些指令序列就是不可被中断的,这就实现了“原子性”。

3.进程控制相关原语

无论哪个进程控制原语,要做的无非三类事情:

1.更新PCB中的信息

2.将PCB插入合适的队列

3.分配/回收资源

①进程的创建

创建原语

创建态→就绪态

申请空白PCB

为新进程分配所需资源

初始化PCB

将PCB插入就绪队列

引起进程创建的事件

用户登录

分时系统中,用户登录成功,系统会建立为其建立一个新的进程

作业调度

多道批处理系统中,有新的作业放入内存时,会为其建立一个新的进程

提供服务

用户向操作系统提出某些请求时,会新建一个进程处理该请求

应用请求

由用户进程主动请求创建一个子进程

②进程的终止

撤销原语

就绪态/阻塞态/运行态>终止态>无

从PCB集合中找到终止进程的PCB

若进程正在运行,立即剥夺CPU,将CPU分配给其他进程

终止其所有子进程(进程间的关系是树形结构)

将该进程拥有的所有资源归还给父进程或操作系统

删除PCB

引起进程终止的事件

正常结束

进程自己请求终止(exit系统调用)

异常结束

整数除以0、非法使用特权指令然后被操作系统强行杀掉

外界干预

Ctrl+Alt+delete,用户选择杀掉进程

③进程的阻塞

阻塞原语唤醒原语必须成对使用

阻塞原语

运行态→阻塞态

找到要阻塞的进程对应的PCB

保护进程运行现场,将PCB状态信息设置为“阻塞态",暂时停止进程运行

将PCB插入相应事件的等待队列

引起进程阻塞的事件

需要等待系统分配某种资源

需要等待相互合作的其他进程完成工作

例如:

读文件磁盘I/O
PV操作执行信号量的wait()操作,如果信号量的值小于或等于0,则进程进入阻塞态
缺页异常当线程检测到缺页异常时,会调用缺页异常处理程序从外存中调入缺失的页面,线程状态由执行转为阻塞

④进程的唤醒

唤醒原语

阻塞态→就绪态

在事件等待队列中找到PCB

将PCB从等待队列移除,设置进程为就绪态

将PCB插入就绪队列,等待被调度

引起进程唤醒的事件

等待的事件发生,因何事阻塞,就应由何事唤醒

⑤进程的切换

运行态→就绪态

就绪态→运行态

切换原语

将运行环境信息存入PCB

PCB移入相应队列

选择另一个进程执行,并更新其PCB

根据PCB恢复新进程所需的行环境

引起进程切换的事件

当前进程时间片到

有更高优先级的进程到达

当前进程主动阻塞

当前进程终止

七.进程的通信

进程间通信(Inter-Process Communication,IPC)是指两个进程之间产生数据交互。

进程是分配系统资源的单位(包括内存地址空间),因此各进程拥有的内存地址空间相互独立

为了保证安全,一个进程不能直接访问另外一个进程的地址空间。这个时候进程间需要通信的话就需要操作系统来支持了。

1.共享存储

为避免出错,各个进程对共享空间的访问应该是互斥的

各个进程可使用操作系统内核提供的同步互斥工具(如P、V操作)

基于数据结构的共享

基于数据结构的共享:比如共享空间里只能放一个长度为10的数组。这种共享方式速度慢、限制多,是一种低级通信方式

注意:这里可不是程序中定义的全局变量。

基于存储区的共享

基于存储区的共享:操作系统在内存中划出一块共享存储区,数据的形式、存放位置都由通信进程控制,而不是操作系统。这种共享方式速度很快,是一种高级通信方式。

2.消息传递

进程间的数据交换以格式化的消息(Message)为单位。进程通过操作系统提供的“发送消息/接收消息”两个原语进行数据交换。

直接通信方式

消息发送进程要指明接收进在的iD

点名道姓的消息方式

间接通信方式

通过信箱,间接的进行通信。

可以多个进程往同一个信箱send消息,也可以多个进程从同一个信箱中receive消息

间接通信方式,以“信箱”作为中间实体进行消息传递。

3.管道通信

“管道”是一个特殊的共享文件,又名pipe文件。其实就是在内存中开辟一个大小固定的内存缓冲区

1.管道只能采用半双工通信,某一时间段内只能实现单向的传输。如果要实现双向同时通信,则需要设置两个管道。

2. 各进程要互斥地访问管道(由操作系统实现)

3当管道写满时,写进程将阻塞,直到读进程将管道中的数据取走,即可唤醒写进程

4当管道读空时,读进程将阻塞,直到写进程往管道中写入数据,即可唤醒读进程。

5管道中的数据一旦被读出,就彻底消失。因此,当多个进程读同一个管道时,可能会错乱。对此,通常有两种解决方案:

  • 一个管道允许多个写进程,一个读进程(2014年408真题高教社官方答案);
  • 允许有多个写进程,多个读进程,但系统会让各个读进程轮流从管道中读数据(Linux的方案)。

八.线程的概念

1.什么是线程,为什么要引入线程?

例如进程微信下有俩线程,引入线程后调度的基本单位就不是整个进程了,而是更小的线程。

线程(Thread)是操作系统管理下的执行单元,它是一个程序执行过程中最小的调度单位。线程在某种程度上可以看作是一个轻量级的进程。每个进程至少包含一个线程(主线程),并且可以包含多个线程。

线程的引入原因:

  1. 并发执行:线程允许程序在同一个进程中同时执行多个任务。通过多线程,可以实现任务的并行化或并发化,提高程序的运行效率。
  2. 资源共享:多个线程共享进程的资源(如内存、文件描述符等),因此在线程间的通信和数据共享上比进程间的通信更加高效。
  3. 响应更快:多线程程序可以在执行某些任务时保持对用户的响应,比如在文件下载的同时还能继续执行其他操作,这样能提高程序的用户体验。
  4. 利用多核处理器:现代计算机通常有多个处理器核心,多线程程序可以同时在多个核心上运行,充分利用硬件资源,提升性能。
  5. 简化设计:一些任务可以被分解为多个独立的子任务,这些子任务可以在多个线程中并行执行,从而简化程序的设计。

引入线程的主要目的就是提高程序的并发能力执行效率,同时保持对资源的高效利用和及时响应。

2.引入线程带来的变化

引入进程前引入进程后

资源分配、调度

传统进程机制中,进程是资源分配、调度的基本单位

引入线程后

进程是资源分配的基本单位,

线程是调度的基本单位

并发性

传统进程机制中,只能进程间并发

引入线程后,各线程旬也能并发,提升了并发度

系统开销

传统的进程间并发需要切换进程的运行环境,系统开销很大

引入线程后,进程下的所有线程共享同一地址空间

代码段,数据段,文件等等都是进程的资源,线程可以共享

只有线程TCB中的例如栈指针是线程独有的,不可共享

线程间并发,如果是同一进程内的线程切换,则不需要切换进程环境,系统开销小

引入线程后,并发性带来的系统开销减小

3.线程的属性

线程是处理机调度的单位

多CPU计算机中,各个线程可占用不同的CPU

每个线程都有一个线程ID、线程控制块(TCB)

线程也有就绪、阻塞、运行三种基本状态

线程几乎不拥有系统资源

同一进程的不同线程间共享进程的资源

同一进程中的线程切换,不会引起进程切换

由于共享内存地址空间,同一进程中的线程间通信甚至无需系统干预

不同进程中的线程切换,会引起进程切换

切换同进程内的线程,系统开销很小

切换进程,系统开销较大

九.线程的实现方式

1.用户级线程

早期的操作系统(如:早期Unix)只支持进程:不支持线程。当时的“线程”是由线程库实现的

1.用户级线程由应用程序通过线程库实现:所有的线程管理工作都由应用程序负责(包括线程切换)

2.用户级线程中,线程切换可以在用户态下由应用程序即可完成,无需操作系统干预

         像:系统调用,I/O请求,异常处理这些涉及内核态的事件都不会导致用户线程切换。

        但是像跨进程的线程进行切换时,实际上就是进程的调度了,需要操作系统内核参与。

3.在用户看来,是有多个线程。但是在操作系统内核看来,并感知不到线程的存在。“用户级线程”就是“从用户视角看能看到的线程

4.优点:用户级线程的切换在用户空间即可完成,不需要切换到核心态,线程管理的系统开销小,效率高

5.缺点:当一个用户级线程被阻塞后,整个进程都会被阻塞,并发度不高。多个线程不可在多核处理机上并行运行。

2.内核级线程

内核级线程(Kernel-LevelThread,KLT, 又称“内核支持的线程”) 由操作系统支持的线程

1.内核级线程的管理工作由操作系统内核完成。

2.线程调度、切换等工作都由内核负责,因此内核级线程的切换必然需要在核心态下才能完成。

3.操作系统会为每个内核级线程建立相应的TCB(Thread ControlBlock,线程控制块)通过TCB对线程进行管理。“内核级线程”就是“从操作系统内核视角看能看到的线程

4.优缺点

优点:当一个线程被阻塞后,别的线程还可以继续执行,并发能力强。多线程可在多核处理机上并行执行。

缺点:一个用户进程会占用多个内核级线程,线程切换由操作系统内核完成,需要切换到核心态,因此线程管理的成本高,开销大。

十.多线程模型

在支持内核级线程的系统中,根据用户级线程和内核级线程的映射关系,可以划分为几种多线程模型

1.一对一

思想一对一模型:一个用户级线程映射到一个内核级线程。每个用户进程有与用户级线程同数量的内核级线程。
优点:当一个线程被阻塞后,别的线程还可以继续执行,并发能力强。多线程可在多核处理机上并行执行。
缺点:一个用户进程会占用多个内核级线程,线程切换由操作系统内核完成,需要切换到核心态,因此线程管理的成本高,开销大。

2.多对一

思想多对一模型:多个用户级线程映射到一个内核级线程。且一个进程只被分配一个内核级线程。
优点用户级线程的切换在用户空间即可完成,不需要切换到核心态,线程管理的系统开销小,效率高
缺点当一个用户级线程被阻塞后,整个进程都会被阻塞,并发度不高。多个线程不可在多核处理机上并行运行。

重点重点重点:操作系统只“看得见”内核级线程,因此只有内核级线程才是处理机分配的单位

3.多对多

思想多对多模型:n用户及线程映射到m个内核级线程(n>=m)。每个用户进程对应m个内核级线程。
优点克服了多对一模型并发度不高的缺点(一个阻塞全体阻塞),又克服了一对一模型中一个用户进程占用太多内核级线程,开销太大的缺点
理解

可以这么理解用户级线程是“代码逻辑”的载体内核级线程是“运行机会”的载体

内核级线程才是处理机分配的单位。

例如:多核CPU环境下,上图这个进程最多能被分配两个核。

一段“代码逻辑”只有获得了“运行机会”才能被CPU执行

内核级线程中可以运行任意一个有映射关系的用级线程代码,只有两个内核级线程中正在运行的代码逻辑都阻塞时,这个进程才会阻塞

十一.线程的状态与转换

与进程的切换一样:

十三.线程的组织与控制

与进程的PCB十分类似

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值