计算机基础文章目录
关于自己对计算机基础内容的整理
网络相关link.
参考了GitHub上的相关内容:cs-notes javaGuide waking-up
文章目录
前言
是对javaguide、cs-nodes等的整理
提示:以下是本篇文章正文内容,下面案例可供参考
一、操作系统基础
什么是操作系统
操作系统(Operating System,简称 OS)是管理计算机硬件与软件资源的程序,是计算机的基石。
os本质上是一个运行在计算机上的软件程序 ,用于管理计算机硬件和软件资源。
os存在屏蔽了硬件层的复杂性。 操作系统就像是硬件使用的负责人,统筹着各种相关事项。
os的内核(Kernel)是操作系统的核心部分,它负责系统的内存管理,硬件设备的管理,文件系统的管理以及应用程序的管理。
什么是系统调用
进程在系统中运行过程中有两个状态
- 用户态:在用户态运行的进程可以访问用户程序的数据
- 系统态:在系统态运行的进程可以访问几乎可以访问任何系统资源而不受限制
通常情况下,进程都是运行在用户态下,但是此状态下的进程无法访问系统资源,因此就需要系统调用,用来处理操作系统提供的系统态级别的功能
也就是说我们的进程运行在用户态,当需要系统态级别的资源操作(文件操作、进程控制、内存管理等)的时候,就通过系统调用向操作系统发起服务请求,有操作系统代为完成。
系统调用分类:
- 设备管理:完成设备的请求和释放,及启动等功能
- 文件管理:完成文件的读、写、创建等操作
- 进程控制:完成进程的创建、撤销、阻塞及唤醒功能
- 进程通信:完成进程之间的消息传递或信号传递功能
- 内存管理:完成内存的分配、回收以及获取占用内存大小和地址等功能
进程和线程的区别
- 进程(Process)是操作系统进行资源分配和调度的基本单位,线程(Thread)是cpu进行调度和分配的基本单位
- 线程依赖于进程存在,每个进程都最少有一个线程
- 地址空间:进程有自己的地址空间,线程共享进程的地址空间
- 资源分配:进程是拥有系统资源、能发起系统调用的一个独立单位,线程基本上不拥有系统资源,只拥有部分必不可少的资源(程序计数器、一组寄存器和栈)并与其他线程共享该进程内的相关资源(内存、io、cpu等)
- 切换:进程切换时,涉及到cpu保存环境现场,而线程切换仅需要保存和设置少量的寄存器,因此线程切换开销远小于进程切换
- 通信:线程通信更方便,同一进程的多个线程之间共享全局变量,进程间通信则需要进程通信(IPC)的方式进行
- 崩溃:多线程中只要有一个线程崩溃,整个程序就停止运行,多进程时单个进程崩溃不影响其他进程
同一进程的多线程共享哪些数据
- 进程代码段
- 进程共有数据(全局变量、静态变量等)
- 进程打开的文件描述符
- 进程当前目录
- 进程id和进程组id
线程独占哪些资源
- 线程id
- 一组寄存器的值
- 线程自身的栈(堆是共享的)
- 错误返回码
- 信号掩码
进程有哪几种状态
- 创建状态(new):进程被创建但未进入就绪状态
- 就绪状态(ready):进程处于准备运行状态,即进程获得除处理器之外的所有资源,一旦获得处理器资源(cpu分配的时间片)即可运行
- 运行状态(runnable):进程正在处理器上运行
- 阻塞状态(waiting):(等待状态)进程等待某时间而暂停运行,如等待某资源为可用或等待io操作完成等,即使处理器空闲,该进程也不能运行
- 结束状态(terminated):进程结束
进程通信方式
- 管道(Pipe)
- 半双工,数据单向流动;数据通信需要双方建立两条管道;
- 发送消息的进程向管道写入的内容被接受进程从管道中读出;写入内容每次都追加到管道缓冲区末尾,读取内容每次都是从缓冲区头部开始读
- 只能用于父子进程或兄弟进程通信(具有亲缘的进程)
- 命名管道
- 消息队列
- 信号(Signal)
- 共享内存
- 信号量
- 套接字(Socket)
进程调度算法
- 批处理系统:没有太多用户操作,该系统中的调度目标是保障吞吐量和周转时间
1.1 先来先服务(FCFS):非抢占式调度算法,按请求顺序进行调度,适用于长作业
1.2 短作业优先(SJF):非抢占式调度算法,按估算时间最短的顺序调度,长作业有可能被饿死
1.3 最短剩余时间有限(SRTN):最短作业优先的抢占式版本,按剩余运行时间的顺序进行调度,新作业到底是和当前作业剩余时间进行比较 - 交互式系统:
2.1 时间片轮转:所有就绪进程按FCFS排成一个队列,每次调度cpu把时间片分给队头的进程,若队头进程在时间片内未结束,则移动到队尾
2.2 优先级调度:为每个进程分配优先级,cpu按优先级进行调度,相同优先级时按FCFS进行调度,并按时间推移增加低优先级进程的优先级
2.3 多级反馈队列:设置多个就绪队列,优先级一次递减,时间片依次递增。只有更高优先级的队列为空时,才会调度当前队列的进程,若该进程时间片耗光为执行完,则移入下一优先级的队列
什么是僵尸进程
子进程结束之后,父进程并没有等待它(wait或waitpid),子进程将成为僵尸进程。即已经死亡,但没有真正被销毁
- 放弃所有内存空间
- 没有任何可执行代码
- 不能被调度
- 在进程表中占位(进程id、中止状态、资源利用信息:cpu时间,内存使用量,这些信息是为了供父进程收集)
危害:占用进程号,系统能使用的进程号是有限的
如何避免僵尸进程: - 父进程结束时,若子进程还没有结束,系统会扫描是否存在子进程,并用Init进程接管子进程,最终调用wait等待其结束
- 父进程调用wait 或 waitpid等待子进程结束
- 子进程结束时会产生sigchild(signal-child)信号,可以注册信号函数,并在函数中调用waitpid。(信号函数只会调用一次,所以需要循环调用waitpid确保所有结束的子进程被回收)
进程同步(todo)
进程同步是目的,进程通信是手段
管程 Monitor
管程将共享变量及对共享变量的操作封装起来,形成具有一定公共模块的接口。
进程通过互斥的使用管程,实现进程同步,使用完毕之后必须释放管程并唤醒等待队列中的进程。
当进程试图进入管程时,在入口等待队列等待。若进程P唤醒进程Q,则进程Q先执行,P在紧急等待队列等待
线程同步方式
多个共享资源的线程并发执行时,应避免关键资源的使用发生冲突
常见线程同步方式:
- 互斥量:采用互斥对象机制,只有拿到互斥对象的线程才可以访问公共资源。由于互斥对象只有一个,所以可以保证多个资源不能被同时访问。像是java中的synchronized关键字和各种Lock锁机制都是这种机制
- 信号量:允许同一时刻多个线程访问同一资源,但是需要控制并发线程的最大数量
- 事件(Event):Wait/Notify通过通知操作保持多线程同步,还可以方便的实现多线程优先级比较
死锁
什么是死锁
两个或多个进程并发的时候,每个进程都持有部分资源,进入阻塞状态,互相等待其他进程释放资源。这种状态没有改变之前都不能向前推进,称为死锁
死锁产生的必要条件
- 互斥:一个资源一次只能被一个进程持有
- 等待并占有:一个进程至少持有一个资源,并等待另一个被其他进程持有的资源
- 非抢占:已经分配给进程的资源不能被强制性抢占,只能由进程完成任务后自行释放
- 循环等待:若干进程间形成头尾相接的环形循环等待关系,该环路中每个进程都在等待下一个进程释放占有的资源
死锁的处理方式
- 鸵鸟策略
忽略死锁,处理死锁问题的代价很高,为了追求性能,在死锁概率很低或死锁造成影响很小的情况下,可以忽略死锁 - 死锁预防
破坏死锁形成的四个必要条件 - 死锁避免
动态检查资源分配状态,只有系统处于安全状态下才进行资源分配
银行家算法 - 死锁解除
利用抢占:挂起某进程,释放他持有的资源
利用回滚:让某些进程回退到足以接触死锁的地步
杀死进程:强制杀死某进程,直到死锁解除
什么是虚拟内存
每个程序都拥有自己的地址空间,该地址空间被分为等大的页,这些页被映射到物理内存中,但并不是所有的页都需要映射,部分暂时不用的页可以放在磁盘中。当程序引用了不在物理内存中的页时,由操作系统将缺失的页装载入物理内存。
对于程序来说,逻辑上就有很大的内存空间,而实际上有一部分是存储在磁盘上的。