文章目录
并发和并行
并发是指一个处理器处理同时处理多个任务的能力。
系统只有一个CPU时,当有多个线程运行时,它在一个时间点只能运行一个线程。即一个 CPU在同一时间是只能做一件事情的。为了看起来像是“同时干多件事”,操作系统将CPU运行时间划分成长短基本相同的时间区间,即”时间片”,通过操作系统的管理,将这些时间片依次轮流地分配给各个任务使用。某个任务在时间片结束后仍然还没有完成,那么该任务就被暂停下来,放弃CPU,等待下一轮循环再继续做,此时CPU又分配给另一个任务去使用。由于计算机的处理速度很快,多个任务之间看起来像是同时执行的,实际是交换执行的。
一个线程运行时,其他线程将处于挂起状态。
并发的多个任务之间是互相抢占资源的。
并行是指多个处理器同时处理多个不同的任务。
系统有多个CPU时,当有多个线程运行时,一个CPU执行一个任务时,另一个CPU执行另一个任务,进程之间互不抢占CPU资源,并且同时进行。
并行的多个任务之间是不互相抢占资源的。
进程
进程是正在运行的一个程序。程序一旦运行起来,它就是一个进程。它是操作系统分配资源的最小单位。
进程的组成
进程由程序、数据和进程控制块(PCB)三部分组成;
1.PCB
PCB包含了OS所需的、用于描述进程当前状况以及控制进程的全部信息,是进程存在的唯一标志。系统通过PCB来感知进程,控制进程。
PCB集中反映一个进程的动态特征,创建一个进程时,首先创建其PCB,然后根据PCB中的信息对进程实施有效的管理和控制。当一个进程完成其功能时,系统会通过释放PCB来释放进程所占有的各种资源,进程也随之消亡。
主要有进程描述信息、进程控制和管理信息、资源分配清单和处理机相关信息。
2.程序段:存放要执行的代码。
3.数据段:存放程序运行过程中处理的各种数据。如全局变量、局部变量、宏定义的常量就存放在数据段内。
创建进程的步骤
- 分配内存空间:操作系统为新进程分配内存空间,用于存储进程的代码、数据和栈等。
- 初始化进程环境:操作系统为新进程初始化环境,包括设置进程标识符、进程状态、进程优先级等。
- 分配资源:操作系统为新进程分配所需的系统资源,如文件描述符、信号处理器等。
- 设置进程控制块:操作系统为新进程创建进程控制块,用于存储进程的相关信息。
- 调度进程:操作系统根据进程的优先级和资源需求来决定进程的执行顺序,并将新进程加入到就绪队列中。
进程的地址空间
进程地址空描述了一个进程在运行时所能访问的虚拟地址范围。每个进程都有自己独立的地址空间,使得多个进程可以同时运行而互相不干扰。在这个地址空间内,操作系统会进行地址映射,将进程的虚拟地址映射到物理内存上,以实现对内存的访问和管理。
当一个进程被创建时,操作系统会为该进程分配一块内存空间,用来存放进程的地址空间。这个地址空间是虚拟的,因为它并不直接对应物理内存中的连续空间,而是通过页表和页表项来映射到物理内存中的不同位置。
.text:用于存放程序执行代码(即CPU执行的机器指令)。
.data:存放程序中已初始化且初值不为0的全局变量和静态局部变量。
.bss:存放未初始化的全局变量和静态局部变量
堆:动态申请内存区域
内存映射:文件映射、加载动态库、匿名映射
用户态和内核态
用户态和内核态是操作系统的两种运行级别,两者最大的区别就是特权级不同。用户态拥有最低的特权级,内核态拥有较高的特权级。运行在用户态的程序不能直接访问操作系统内核的数据结构和程序。内核态和用户态之间的转换:系统调用、异常、中断。
CPU的某些指令,有些指令如果用错,将会导致整个系统崩溃。分了内核态和用户态,用户操作这些指令,内核为其提供了API,可以通过系统调用陷入内核,让内核去执行这些操作。
进程的特征
1. 动态性:进程的最基本的特征,进程是程序的一次执行过程,是动态的产生、变化和消亡。
2. 并发性:内存中有多个进程实体,各进程可并发执行。
3. 独立性:进程是能独立运行、独立获得资源、独立接受调度的基本单位。
4. 异步性:各个进程按各自独立的、不可预知的速度向前推进,操作系统要提供进程同步机制来解决异步问题。
5. 结构性:每个进程由程序段、数据段和PCB组成。
进程的状态
就绪态:进程已经分配除CPU以外的所有必要资源,只要在获得CPU就可立刻执行。
执行态:进程已获得CPU,其程序正在执行的状态。
阻塞态:正在执行的进程由于发生某事件(如IO请求、申请缓冲区失败等)暂时无法继续执行的状态。
孤儿进程
父进程先于子进程退出,子进程就变成孤儿进程。init进程会领养这个孤儿进程。
进程退出的时候,进程的用户区可以自己释放,但是进程内核区的PCB资源自己无法释放,必须要由父进程来释放子进程的PCB资源,孤儿进程被领养之后,可以避免了系统资源的浪费。
僵尸进程
子进程退出的时候,需要父进程释放自己的PCB资源,如果父进程不管,子进程就会变成僵尸进程。僵尸进程需要父进程调用wait()或waitpid()来进行子进程资源的回收。
僵尸进程时每个子进程退出时必然经历的过程
守护进程
守护进程是linux后台服务进程,独立于可控制终端且周期性执行某种任务或者等待处理某些发生的事件。
进程的调度算法
先来先服务调度算法
最短作业优先调度算法
时间片轮转调度算法
高响应比优先调度算法
最高优先级调度算法
多级反馈队列调度算法
进程的通信方式
匿名管道
管道的本质是内核中的一个固定大小为4K的环形队列,分为读端和写端,数据只能单向流动,从读端流出,写端流入,从写端流向读端。数据只能读取一次。
匿名管道只能实现有血缘关系的进程间通信。
有名管道
有名管道在磁盘上有实体文件,文件类型为p,它的文件大小永远为0,因为有名管道的也是将数据存储到内存的缓冲区中,打开这个磁盘上的管道文件就操作有名管道的文件描述符,通过文件描述符读写管道存储在内核中的数据。
有名管道只有一端打开,会出现阻塞,直到另一个进程讲管道的对端打开,当前进程的阻塞就会解除。
内存映射
每个进程的用户空间存在一块内存映射区。进程通信使用的内存映射区不是一块,而是在每个进程内部都有一块。
需要通信的进程将各自的内存映射区和同一个磁盘文件进程映射,磁盘文件数据可以完全或部分加载到进程的内存映射区,当进程A中的内存映射区数据被修改了,数据就会被自动同步到磁盘文件,同时和磁盘文件建立映射关系的其他进程内存映射区中的数据也会和磁盘文件进行数据的实时同步,这个同步机制保障了各个进程之间的数据共享。
共享内存
共享内存不同于内存映射区,它不属于任何进程,并且不受进程生命周期的影响。
使用共享内存之前,将进程与共享内存进行关联,得到共享内存的起始地址,进行读写操作。进程也可以和这块共享内存解除关联,解除关联之后就不能操作这块共享内存了。在所有进程间通信方式,共享内存的效率是最高的。
进程的优缺点
优点:进程相对比较稳定安全,因为每一个进程都拥有独立的系统资源,进程间不容易相互影响,而且因为不会共享数据 的问题,所以无需对进程作同步操作。
缺点:进程的建立及切换(context switching) 的开销都比较大,因为涉及到系统资源的切换,进程之间要通信也比较复杂及耗时。
线程
线程(thread) 是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位,即进程执行的任务,其实是由进程里面的线程去做的。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
线程是最小的执行单元,而进程由至少一个线程组成。
对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程,打开一个Word就启动了一个Word进程。
有些进程还不止同时干一件事,比如Word,它可以同时进行打字、拼写检查、打印等事情。在一个进程内部,要同时干多件事,就需要同时运行多个“子任务”,我们把进程内的这些“子任务”称为线程(Thread)。
如何调度进程和线程,完全由操作系统决定,程序自己不能决定什么时候执行,执行多长时间。多线程在共享资源会出现竞争问题,需要通过同步机制解决。
线程的组成
创建一个线程需要的内存空间是MB级别
- 线程ID
- 程序计数器PC
- 寄存器
- 线程栈
进程和线程的区别
-
进程是CPU分配资源的最小单位,线程是CPU调度的基本单位。
-
进程有独立的系统资源或地址空间,而同一进程内的线程共享进程的大部分资源,包括堆、代码段、数据段,每个线程只拥有一些在运行中必不可少的私有属性,如线程id、线程栈、寄存器、程序计数器PC。
-
一个进程崩溃,不会对其他进程产生影响,而一个线程崩溃,会导致同一进程内的其他线程也挂掉。
-
进程在创建、销毁时开销较大。进程创建时需要分配虚拟地址空间等系统资源,销毁时需要释放系统资源,线程只需要创建栈,栈指针,程序计数器,通用目的寄存器和条件码等,不需要创建独立的虚拟地址空间。
-
进程切换开销比较大,线程比较小。进程切换需要切换页目录,刷新TLB以使用新的地址空间;切换内核栈和硬件上下文(寄存器);而同一进程的线程间逻辑地址空间时一样的,不需要切换页目录,刷新TLB、
-
进程间通信比较复杂,而同一进程的线程由于共享代码段和数据段,通信较容易。
线程间共享和私有资源
私有:线程栈,寄存器、程序寄存器、线程id、错误返回码、信号屏蔽字、调度优先级
共享:文件描述符列表,堆段,页表,数据段,进程代码段,进程的当前目录和进程用户id与进程组id