(本文只是自己的学习总结,不一定正确,仅供参考)
进行本地计算机或网络资源管理,合理分配计算、时间、存储、带宽等资源,提供与用户进行交互的界面。
常见操作系统有实时操作系统ucos,非实时操作系统linux、windows等。
在宏观时间上可以同时并发执行多个进程,但实际上在微观的CPU时间上是串行进行的。
把处理器的运行时间分成很短的时间片,按时间片轮流把处理器分配给任务使用。
某些硬件资源、某些存储在内存上的数据可以由多个进程共享。
系统中的某些资源,如打印机、磁带机,虽然它们可以提供给多个进程使用,但为使所打印或记录的结果不致造成混淆,应规定在一段时间内只允许一个进程访问该资源。
系统中还有另一类资源,允许在一段时间内由多个进程“同时”对它们进行访问。这里所谓的“同时”往往是宏观上的,而在微观上,这些进程可能是交替地对该资源进行访问即
“分时共享”。典型的可供多个进程“同时”访问的资源是磁盘设备。
操作系统把物理上的硬件资源虚拟成软件上的表达(比如linux上所有的I/O设备都虚拟成文件),通过用户界面展现给用户。也可以把一个物理实体虚拟成多个(多个终端,硬盘分区等),把多个物理实体虚拟成一个(分布式)。
进程以异步方式执行,在微观上不确定何时执行哪个进程。
分时操作系统把处理器的运行时间分成很短的时间片,按时间片轮流把处理器分配给任务使用,分时操作系统可以实现多个用户通过终端同时共享一台主机,实现人机交互。大多数常见的操作系统都是分时操作系统。
实时操作系统能对外部的信息在规定的时间(比时间片的时间还短)内作出处理(比如飞机订票系统、工业控制系统、导弹制导系统)。多用于工业生产控制以及特殊领域,比如ucOS-Ⅱ等。
网络操作系统把计算机网络中的各台计算机有机地结合起来,提供一种统一、经济而有效的使用各台计算机的方法,实现各个计算机之间的互相传送数据。网络操作系统最主要的特点是网络中各种资源的共享以及各台计算机之间的通信。
分布式计算机系统是由多台计算机组成并满足下列条件的系统:系统中任意两台计算机通过通信方式交换信息;系统中的每一台计算机都具有同等的地位,即没有主机也没有从机;
每台计算机上的资源为所有用户共享;系统中的任意若千台计算机都可以构成一个子系统,并且还能重构;任何工作都可以分布在几台计算机上,由它们并行工作、协同完成。用于管理分布式计算机系统的操作系统称为分布式计算机系统。该系统的主要特点是:分布性和并行性。分布式操作系统与网络操作系统本质上的不同之处在于分布式操作系统中,若干台计算机相互协同完成同一任务。
分布式系统是去中心化、自适应、并行运算的。
串行:同一时刻只能执行一项任务。单处理器单核的都是串行。
并行:同一时刻可以执行多项任务。多核或者多处理器可以并行执行。
并发:同一时间段可以执行多项任务。其在微观的时刻可以是串行也可以是并行。
分布式:在并行基础上,任务在物理设备上是分开的。
同步:多个任务情况下,一个任务A执行结束,才可以执行另一个任务B。只存在一个线程。
异步:多个任务情况下,一个任务A正在执行,同时可以执行另一个任务B。任务B不用等待任务A结束才执行。存在多条线程。用户进程触发IO
操作以后便开始做自己的事情,而当IO 操作已经完成的时候会得到IO
完成的通知。
阻塞和非阻塞是针对于进程在访问数据的时候,根据IO操作的就绪状态来采取的不同方式,说白了是一种读取或者写入操作方法的实现方式,阻塞方式下读取或者写入函数将一直等待,而非阻塞方式下,读取或者写入方法会立即返回一个状态值。
以银行取款为例:
阻塞 :
ATM排队取款,你只能等待(使用阻塞IO时,Java调用会一直阻塞到读写完成才返回);
非阻塞 :
柜台取款,取个号,然后坐在椅子上做其它事,等号广播会通知你办理,没到号你就不能去,你可以不断问大堂经理排到了没有,大堂经理如果说还没到你就不能去(使用非阻塞IO时,如果不能读写Java调用会马上返回,当IO事件分发器通知可读写时再继续进行读写,不断循环直到读写完成)
读:读取查询等操作,不影响内容。
写:增删改操作,会改变原来的内容。
执行:可执行的程序,能够对其他文件产生读写等操作。
嵌入式硬件、手机等。
linux可编译进ARM架构运行。
安卓天生支持ARM。
微软Windows不支持ARM。
桌面电脑、服务器,windows/macos/linux等大多基于x86。
——只支持64位软件,因为AMD抢先研发出了64位处理器,所以命名为AMD64
——主要支持64位软件,也向下兼容32位软件
——只支持32位软件
x86的细分:
i386对应的是32位系统
i686是i386的一个子集,取消对旧版本的兼容,是更新的版本
i386 适用于intel和AMD所有32位的cpu
i686适用于新的CPU,i3/i5/i7等全都支持
MIPS、PowerPC等
加电自检,启动出厂固化在主板上BIOS程序,处理基本的IO操作,启动显卡、硬盘、内存等基本计算机组分,载入Bootloader。
存放在硬盘起始位置的OS加载程序,首先加载到内存中,是一个微小操作系统,把硬盘中实际操作系统OS加载到内存中,把控制权移交给OS。
拿到控制权后,即开启正常OS启动过程,以及启动后的正常工作。计算机运行中OS会一直常驻内存。
中断:也称外中断。由设备发出,操作系统处理
异常:也称内中断。由程序执行过程中意想不到的事件发出,由操作系统抛出异常然后进行对应的处理
系统调用:程序主动向操作系统发出服务请求,操作系统处理。一般封装成系统API
封装系统调用到更高层次,更加方便程序使用。
WIN32 API——windows系统
POSIX API——unix/linux/mac os系统
进程是操作系统上应用程序运行的基础。
每一个应用程序进程都有唯一的进程PID。
一个进程就是一个应用程序运行的生命周期。
操作系统对进程进行自动管理。
一个进程是具有独立功能的程序在一个数据集合上的一次动态执行过程。
动态性(动态创建执行结束);并发性(多进程);独立性;制约性(访问数据或资源存在互斥冲突)。
一个进程应该包括:程序的代码;程序处理的数据;指令计数器;堆栈空间;系统资源(比如占用CPU、内存、网络、外设、打开文件等)。
操作系统为每一个进程生成一个PCB(进程控制块,链表),其ID即进程唯一标识PID。
PID包含本进程PID、父进程PID、用户名信息。
对每种进程状态建立状态队列,管理进程状态,进行进程调度。
创建进程的三种事件:系统初始化;用户发起创建;进程发起创建。建立PCB-PID。
进程创建新进程:通过系统调用。exec()——覆盖父进程,对外显示为同一进程;fork()——复制父进程的所有数据,建立新进程PID;wait()——等待子进程返回结果并辅助彻底结束子进程。
已获取所有需要的非计算资源,就差进入CPU进行计算执行了。
获取包括CPU的所有资源,进入执行。
微观上,一个CPU内核同一时刻只能有一个进程处于执行状态。CPU调度的时间片轮转,会让各种进程在就绪态和运行态不断循环。
宏观上,同一时刻会有多个进程正在运行。
进程发生某种事件(如I/O请求不能满足等)暂停执行的状态。
唤醒:只能被别的进程或操作系统唤醒,要么直接执行,要么进入就绪队列随后执行。
从内存转移到外存等待。
阻塞挂起:优先进行阻塞挂起。
就绪挂起:没有阻塞进程时,选择优先级低的进程挂起。
自愿正常退出;自愿错误退出;致命错误,由操作系统强制退出;被其他进程强制退出。
进程自愿退出:通过系统调用。exit()——销毁自身占用的所有资源,在用户态内消失,但PCB-PID并未消失,成为僵尸态,需要通过父进程wait()辅助。
两个进程之间的通信,通信数据包括发送send和接受receive
直接通信:共享内存
间接通信:消息队列
软件中断,软件进程收到信号后进行各种处理。只传递简单的信号,不能传递数据。
Unix/linux使用的策略,父进程向子进程传递字节流。
Shell终端写命令时可利用管道把输入输出重定向。
间接通信,新建一个变量——消息队列,通信双方向消息队列发送或接收数据实现通信。传递的是有数据结构可解析的信息。
在内存中建立共享的地址区间,多个进程可共享,直接通信。但有并发调度的问题,要建立互斥锁机制。
多用于网络通信。
线程是比进程更小的能独立运行的基本单位,是进程的子单位。
一个正在运行的多线程程序在操作系统层面只有一个进程PID。
多线程几乎只占用一个进程的资源,可以减少计算机的开销。
同一个进程内的所有线程共享内存资源(包括代码段、数据段、进程PID、文件操作符),各线程独享CPU寄存器和堆栈。
线程也可并发执行,也有就绪、运行、阻塞状态。
进程是资源分配单位,线程是CPU调度单位。
进程由操作系统创建结束和调度,线程由程序自身创建结束和调度。
一个进程初始的线程就是主线程,子线程由主线程创建。
默认没有守护线程,当所有子线程执行完毕后主线程才能退出。
守护线程:守护线程在后台默默工作,当所有非守护线程都消失时,守护线程自动退出。对一个多线程程序设置守护线程,则主线程不必等其他线程,可以提前退出。
先来先运行
减少各个进程的等待时间
减少额外花费的切换时间
轮流分享
自动根据占用的时间片建立优先级
用户维度的公平而非进程维度的公平
硬实时:必须要满足实时性,不得有超越实时性要求的延迟
软实时:可以允许偶尔延迟
周期越短优先级越高
Deadline越早优先级越高
比较复杂。
次高级进程提前抢占了最高级进程需要的资源,导致最高级进程一直等待。
解决方法:优先级继承、优先级天花板(把资源的优先级定为最高级)
并发执行多条类似指令,对同一共享数据进行改动,可能发生冲突,产生不确定性。
解决:首先要在进程调度和线程调度时,一定要保证读写数据的指令的原子性。然后还需要加入锁机制。
一个可执行进程,被调度器持续忽略,得不到应得的资源,导致一直处于可执行状态却不能执行。
锁带来的问题,两个或以上的进程,自己已经拿到了一部分资源但还需要其他资源,但其他资源又被其他进程占用,相互等待,导致没有一个进程能够顺利执行,陷入死循环。
解决:
死锁预防——无抢占,要么全拿到,要么拿不到全部则释放已经拿到的,对所有资源排序,按照资源的顺序进行申请;
死锁避免——当进程申请资源的时候,系统会检查申请的后果,尽量避免死锁的发生;
死锁检测——通过算法对运行中的系统进行扫描检测,发现死锁现象。
死锁恢复——把死锁的进程杀掉,资源抢占。
假设资源就是银行里的资金,进程就是银行的客户。
前提条件:多个进程、多个资源;每个进程都尽可能地利用资源;如果进程得不到资源就等待;进程拿到全部需求的资源后在有限的时间内释放资源。
数据结构:
n=进程数量,m=资源类型数量。
总需求量max——nxm矩阵。矩阵元素存储每个进程请求每种资源的数量。
剩余空闲量avilable——m向量。存储每种资源的剩余可用数量。
已分配量allocation——nxm矩阵。存储已分配给每个进程的每种资源数量。
未来需要量need——nxm矩阵。每个进程对每种资源的未来需要的数量。
算法:
通过数据结构判断进程申请的资源是否超出了剩余空闲量,未超出则分配,超出则暂时不分配,让进程等待。
同一时刻只能有一个线程能够使用资源,退出时释放给其他线程
如果一个线程想要获得被占用资源,那么最终一定能够成功
其他线程要获取资源的等待时间要有限,不能无限期等待
加锁解锁,实现互斥的功能。加锁则同一时刻只能有一个线程使用,解锁则释放给其他线程。
Lock.acquire()操作:等待直到锁可用,然后抢占锁;
Lock.release()操作:释放锁,唤醒等待者如果有。
一个整形数值,每个线程可调用,调用后即加1或减1,然后判断信号量数值,通过信号量数值控制线程的等待和执行。
P()操作:信号量减1,如果小于0则等待,否则继续;(会阻塞)
V()操作:信号量加1,如果小于等于0,唤醒一个等待的P()。(不会阻塞)
包括:一个锁,多个条件变量。(锁和信号量的综合利用)
物理地址:硬件内存的实际存储地址,存在各种层次。
虚拟地址:操作系统建立的映射到物理地址的虚拟的地址空间(包括内存条上的物理内存、硬盘上的虚拟内存),线性访问。
逻辑地址:程序中的地址编码范围,在程序编译后生成,由编译器决定,线性访问。
一段连续的存储地址空间,空闲块、非空闲块。
不连续的容量比较小的空闲内存块(磁盘碎片同理),难以利用,浪费存储空间。
外部碎片——未分配的内存或磁盘的存储地址片段。
内部碎片——已分配给程序,但程序并不使用,只有当程序退出后操作系统才能重新利用。
按照地址顺序依次寻找可用的空闲块。
优点:逻辑、算法简单,能够保留地址后方的大空闲块。
缺点:容易产生碎片,不确定性。
使用比需求稍大的空闲块,尽可能高效地利用空闲块(见缝插针)。
优点:当大部分分配是小尺寸式非常高效,算法比较简单。
缺点:分配后难以扩展,重分配慢,产生大量小碎片。
使用最大的可用空闲块。
优点:避免产生琐碎的小碎片,分配中等尺寸效果最好。
缺点:重分配慢,会破碎大的空闲块以致大的需求无法被分配。
移动各个非空闲块,使其紧凑排列,则之间的小碎片消失。
利用硬盘(虚拟内存),在硬盘中设置一段交换空间,把等待的程序空间转移到交换空间,腾出空间给活跃的程序。
优点:更好的内存利用和管理、隔离;允许共享代码和数据(运行库);支持动态加载和动态链接。
缺点:管理开销大。
根据功能和特性分散分配到不同的物理地址。
程序访问内存地址需要写二元组:段号+段偏移。
把地址分割成等长的子区间,与物理内存的页帧相关,一般等于页帧或者页帧的2^n倍。一般一页是4kB。
开销比分段小。当前主流的非连续内存分配机制。
寻址:页地址+页偏移。
物理地址的最小分区,与物理内存的硬件结构有关。
存储逻辑页号的索引表。如果逻辑地址很大,那么单级页表也会很大,所以实际系统中使用页表缓存、多级页表。
页表项的内容:逻辑页号、标志位、物理页号。
缓存近期使用过的页,存储在CPU的Cache中,用于快速查询页表。
寻址:一级页地址+二级页地址+页偏移。
不是基于逻辑地址分页(可能远大于物理地址),而是基于物理地址分页,可以减小页表占用的空间。
1.用于内存管理,把等待的内存数据移入硬盘中的虚拟内存(交换技术),需要使用的时候再移入内存。
2.当内存太小甚至占用过多乃至溢出时,可利用硬盘中的虚拟内存临时当作内存使用。
占用硬盘读写,速度慢,减少硬盘寿命。
一个程序会分配到多个逻辑页,在虚拟内存管理中会动态移入移出某些页,程序访问某个页的时候此页可能已经移出内存,这种情况叫缺页,会产生缺页中断。
缺页中断发生的次数应当尽量少。
针对一个程序在物理内存中分配固定的页,但少于程序的需求,因此需要利用虚拟内存进行页面置换。
计算每个页在下一次访问前还需要等待多长时间,选择等待时间最长的页移出。
现实中很难实现,可以作为页面置换算法的评价标准。
记录各个页在内存中滞留的时间,滞留时间最长者(先进者)先出。
记录各个页最近未使用的时间,选择最久未使用的移出。
没看懂?
记录历史访问次数,选择访问次数最少的页移出。
针对多个程序分配页面。
工作集:某个时间区间内的工作集,是在此时间区间内访问过的所有页。
常驻集:长期常驻内存的页。(常驻内存)
常驻集包含于工作集,工作集包含于物理内存。常驻集越多,则能够分配给新程序的物理内存就越少。(例如操作系统占用太多常驻内存,则可使用的内存越少)
保留工作集,替换不在工作集内的页。
动态调整工作集、常驻集,每当发生缺页中断时,就把此页送入工作集、常驻集,以降低缺页率。(自适应算法)
当缺页率高时-增加工作集。
当缺页率低时-减少工作集。
每个文件系统一个,文件系统详细信息,块,块大小,空间管理
每个文件一个,文件详细信息,用户、权限、计数、指针
每个目录一个,所有目录构成树数据结构,父结点、子结点、指向文件控制块
Windows早期文件系统,fat32不支持4G以上的单文件
Windows使用的文件系统,日志功能
Linux使用的文件系统,目前版本ext4,日志功能
网络文件系统
网络文件系统
不是为了数据存储,而是以文件读写的方式展现或交互内核中的数据,Linux中的/proc目录。
Windows通过表面的后缀名识别类型,linux通过文件控制块识别类型。
是一个索引值,指向内核为每一个进程所维护的打开文件的记录表项。
指向打开的文件的最近一次读写位置。
程序进程调用系统的打开文件调用,系统在打开文件表中新建一个文件描述符项,把文件描述符返回给程序,程序后续只需要对此文件描述符进行操作。
记录文件同时打开的次数。
文件在磁盘中分块存储,需要在文件控制块记录文件各个块的地址。
用户、组,读、写、可执行。
系统文件。
库文件。
用户文件。
普通文件。
目录文件。文件夹本身也是文件。
特殊文件。比如linux系统把输入输出设备看作文件。
临时文件。
永久文件。
档案文件。
只读文件。
读写文件。
不保护文件。
输入型文件。
输出型文件。
输入输出型文件。
记录式文件:有逻辑结构,比如数据文件、文档。
流式文件:没有逻辑结构,二进制或字节流存储,比如多媒体文件。
硬链接——多个文件项指向同一个物理存储的文件,删除一个则全删。
软链接——以快捷方式指向其他文件,是一个单独的文件,存储的是其他文件的路径,删除不会影响指向的文件。
每个进程都单独建立一个文件描述符表,前三项为标准输入stdin、标准输出stdout、标准错误stderr,后面为空,随着打开文件一一建立文件描述符。
优点:读写性能最优,高效随机访问
缺点:难以扩展,碎片化
优点:扩展性好,没有碎片
缺点:读性能差,可靠性差(链断则文件崩溃)
(实际使用的存储策略)
优点:可扩展性好,可靠性好,没有碎片,读写性能好(综合了连续存储与链式存储的优点)
缺点:当文件很小时开销大,难以处理大文件(地址空间不足,解决方法是分级索引)
磁盘中的空闲空间也需要建立列表进行统计管理,由磁盘中的文件系统实现。
空闲空间管理列表必须存储在磁盘上,确保内存中的数据与磁盘一致,必须要防止识别错误导致覆盖已有文件。
磁道、扇区:磁盘的存储部分是同心圆,分为多个磁道,每个磁道分为多个扇区。光盘是螺线寻址,磁盘是同心圆线性寻址。
柱面:每个磁道的所有扇区构成的一个圆圈,柱面是硬盘分区的最小单位。磁盘物理上的内外磁道的柱面不一样,外道周长大、柱面多。但逻辑上对外标明的柱面内外道一致。
簇:扇区是硬盘数据存储的最小单位,但操作系统无法对数目众多的扇区进行寻址,所以操作系统就将相邻的扇区组合在一起,形成一个簇。
寻址:当下的磁盘把所有扇区统一编址,从0到最大地址,线性寻址。
卷和分区概念差不多一样。分区只针对一个物理硬盘,卷包括所有的硬盘,每个分配的盘符都是一个卷。
只有windows才对单个物理硬盘进行分区,并分配多个盘符、多个文件系统;unix系的系统只有一个主分区,建立统一的文件系统,根目录/。
磁头位移实现磁道转换,磁盘碟片旋转实现扇区转换,磁头是速度瓶颈,所以在分配磁盘空间的时候尽量减少磁道转换。
目前所有的操作系统中,大致只分为两个体系——类UNIX系、微软系。
类UNIX系分支超级多,造就了了如今绝大多数系统类型。
UNIX
——+UNIX
——+开源分支
————+BSD组织(BSD自由软件协议)
——————+FreeBSD
——————+OpenBSD
——————+MacOS
————————+iOS
——————+GNU组织(GPL/LGPL开源软件协议)
————————+Linux
——————————+Redhat
————————————+Fedora
————————————+CentOS
——————————+Debian
————————————+Ubuntu
————————————+Deepin
——————————+Android
——+商业分支
————+AIX(IBM)
————+HP-UX(HP)
————+Solaris(Sun/Oracle)
微软系分支少,主要受迭代的影响,迭代的差别很大。
MS-DOS(1980)
——Windows桌面系
————Windows1.0/2.0/3.0(1985,开始有图形界面)
————WindowsNT(1995,网络操作系统,首次舍弃DOS,开始32位,内核流传至今)
————Windows1995/1998/2000(1995)
————WindowsME(2000)
————WindowsXP(2001,经典系统经久不衰)
————WindowsVista(2007)
————Windows7(2009,新时代系统)
————Windows8(2012)
————Windows10(2015,当下的核心)
——Windwos Server服务系
————Windows Server2003(2003)
————Windows Server2008(2008)
————Windows Server2012(2012)
————Windows Server2016(2016)
操作系统的老祖宗,linux、macos、以及基于linux的安卓等操作系统都继承自unix。
开源,开放透明
某些发行版常年不变,稳定
软件少,且多需要操作命令行,难用
系统保护,文件与用户权限管理
各种发行版其实大同小异,区别并不大
最优秀的商用版本
Redhat支持的开放版本
源自RedHat的社区免费版,主要优点就是稳定(更新慢)
社区linux的典范。
Debian最具特色的是apt-get/dpkg(deb)包管理方式,其实Redhat和CentOS的yum也是在模仿Debian的apt方式
源自Debian的主流版本,沿用apt-get/dpkg(deb)包管理方式,背后有企业后盾来维护,对中文支持比较好
源自Debian的国产版本,沿用apt-get/dpkg(deb)包管理方式,中国企业深度国产化,最易用,但稳定性可能比较差
商业,封闭
不稳定
软件多,兼容性好,易用
能够通过硬件实时处理的微小操作系统,不使用软件时间分片。
源码公开
美国风河推出