什么是操作系统(OS)?
- 本质上是一个运行在计算机上的软件程序 ,用于管理计算机硬件和软件资源
- 操作系统的存在屏蔽了硬件层的复杂性。
- 操作系统的内核(Kernel)是操作系统的核心部分,它负责系统的内存管理,硬件设备的管理,文件系统的管理以及应用程序的管理。 内核是连接应用程序和硬件的桥梁,决定着系统的性能和稳定性。
1、进程与线程
1.1 进程与线程的联系与区别
进程:进程是一个有独立功能的程序在某个数据集合上的一次运行。
线程:线程是系统调度的最小单位,包含在进程之中。
联系
进程可以有多个线程,最少包含一个线程,即主线程。一个线程只能属于一个进程。线程是进程执行的实体。
区别
- 进程是资源分配的最小单位。进程拥有资源,而线程不拥有资源,但是进程中的多个线程可以共享所属进程中的资源。
- 线程是系统调度的最小单位。
- 进程的创建或撤销,系统需要为它分配或者回收资源,开销远大于线程的创建或撤销。进程间的切换需要保存当前的CPU环境和配置新的CPU环境,而线程间的切换只需要保存和设置少量寄存器,开销较小。
- 进程的崩溃不会引起其他进程的崩溃,而线程的崩溃会引起整个进程的崩溃。
线程占有的都是不共享的,其中包括:栈、寄存器、状态、程序计数器;
线程间共享的有:堆、全局变量、静态变量;
进程占有的资源有:地址空间、全局变量,打开的文件、子进程、信号量、账户信息。
1.2 为什么需要有线程
- 因为进程执行过程中会因为阻塞而导致整个进程挂起,比如等待输入,即使进程中有些不依赖这个资源的工作,仍然不会执行。线程的引入能减少时空开销,更好的实现并发。
- 线程的创建和销毁,只需要保留线程自己的栈区和少量寄存器,而进程的创建和销毁远远大于线程的开销。
1.3 线程的类型
用户级线程
这类线程的管理的所有工作都由应用程序完成。执行一个应用程序,操作系统会为该应用程序分配进程号、内存空间等资源。然后在一个线程上运行这个应用程序,这个线程就是主线程。
优点是非常高效,因为不需要进入内核空间,但是不能很好的实现并发。
内核级线程
这类线程的管理的所有工作都由内核完成。应用程序不能进行线程管理,只能调用内核对外开放的该线程的接口。
优点是内核可以将不同线程分配给不同CPU,更好的实现并发,但是效率不高,需要在用户态和系统态之间不断切换。
1.4 并发和并行
-
并发是指在一段时间内,多个任务都在执行,也就是宏观上看是同时进行的,但是微观上同一时间只有一个任务在执行。多个任务交替执行,交替速度非常快,所以宏观上看是同时的。
-
并行是真正的实现了物理上的同时执行。在同一时刻多个任务同时执行。
程序并发执行可以使系统资源的利用率得到提高,从而提高系统的处理能力
并发和并行的区别
并发,指的是多个事情,在同一时间段内同时发生了。
并行,指的是多个事情,在同一时间点上同时发生了。
并发的多个任务之间是相互抢占资源的。
并行的多个任务之间是不相互抢占资源的。
只有在多CPU系统的情况下,才会发生并行,否则,看似同时发生的事情,其实都是并发执行的。
顺序执行程序的特征
- 顺序性
- 环境的封闭性。独占系统全部资源,不受外界因素的影响。
- 结果的可再现性。程序初始条件保持不变,无论在什么情况下运行,执行结果都是一样的。
并发执行程序的特征
- 并发性
- 共享性
- 制约性
Bernstein条件为了保持程序的可再现性。
1.5 进程的状态
新建、就绪、阻塞、运行、消亡
- 新建:刚刚创建的进程,通常是还没有加载到主存中的新进程。
- 新建->就绪:已具备运行条件,通常将该进程插入就绪队列成为就绪态
- 新建->运行:紧急事件需要立即处理,直接投入运行,称为抢先
- 就绪:进程做好了运行准备,只要获得CPU就可以开始执行。
- 就绪->运行:在就绪队列中等待进入运行态
- 阻塞:进程在等待某些事件,如I/O操作。
- 阻塞->就绪:等待的条件已经满足
- 阻塞->运行:等待事件后需要立即处理
- 运行:进程正在被执行。
- 运行->就绪:时间片用完了,进入就绪
- 运行->阻塞:因为一些资源等待阻塞了,如等待IO输入
- 运行->消亡:进程全部结束成为消亡状态
- 消亡:操作系统从可执行进程组中撤销了进程,或者自身停止,或者因为某种原因被撤销。
进程控制块(PCB)是进程存在的唯一标识,是操作系统对进程进行控制、管理和调度的依据,它在创建进程时产生,在撤销进程时消亡。
1.6 进程间通信(IPC)
临界资源:一次只允许一个进程访问的资源。
临界区:访问临界资源的程序。
对临界资源的访问原则:
- 有空让进
- 忙着等待
- 有限等待
- 让权等待
进程之间的关系
-
进程互斥:多个进程因不能同时访问临界资源而产生的制约关系。
-
进程同步:系统中多个进程中发生的事件存在某种时序关系,需要互相合作,共同完成一项任务。
-
通信:进程之间需要交换数据
信号量:管理相应临界区的公有资源,代表可用资源的实体数。
- 公用信号量:一组互斥关系的进程间共享的信号量。
- 私用信号量:仅供具有同步关系的并发进程间各自独自使用的信号量。
根据信息量的大小可以分为
- 低级通信
- 高级通信
常见的通信方式
无名管道、有名管道、消息队列、信号量、信号、共享内存、套接字
- 无名管道pipe:管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
- 命名管道FIFO:有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
- 消息队列MessageQueue:消息队列是一个消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限制等缺点。
- 共享存储SharedMemory:共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的IPC方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。
- 信号量Semaphore:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同进程内不同进程之间的同步手段。
- 套接字Socket:套接字也是以一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。
- 信号Sinal:信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
共享内存是最快的通信方式,套接字是最常用的通信方式,它可以实现不同主机的进程通信。
数据通常是在两个站(点对点)之间进行传输,按照数据流的方向可分为三种传输模式:
- 单工通信:只支持信号在一个方向上传输(正向或反向),任何时候不能改变信号的传输方向。
- 半双工通信:允许信号在两个方向上传输,但某一时刻只允许信号在一个信道上单向传输(也可理解为可切换方向的单工通信)。
- 全双工通信:允许数据同时在两个方向上传输,即有两个信道。
1.7 死锁
死锁
一个进程集合中的每个进程,都在等待该集合中的其他进程释放资源所形成的僵局,若无外力推进将无法继续执行。
根本原因
系统资源不足,导致资源不够分配
直接原因
进程推进不当
四个必要条件
- 互斥。资源要么被分配给一个进程,要么未分配。
- 不可抢占。进程所占有的资源