写一点OS的基础知识,面试中持续更新...面试
基基础知识算法
1.计算机硬件:输入/输出设备,存储器,运算器,控制器。数据库
2.三种基本OS类型:编程
批处理OS:单道批处理(CPU利用率低),多道批处理(缺少交互性)安全
分时OS:时间片轮转分配;多线程
实时OS:及时响应,高可靠性并发
3.最基本特征:并发和共享异步
4. 并行与并发:并行:真正意义上的同时执行,而并发仍是一个接一个的执行,在一段时间内获得时间片轮转进行执行,一段时间后执行完毕,宏观上并行。socket
进程&线程相关函数
1. 概念:程序在一个数据集合上的一次运行过程,是OS资源分配的基本单位;
2. 动态、并发、独立、异步,一个程序能够包含多个进程;
3. 组成:程序、数据、PCB(标识符、状态-阻塞、就绪、执行)、优先级、CPU现场保护区、家族联系(父子自之间的关系)、占有资源的清单
4. 状态:就绪阻塞和执行,三个队列。当就绪状态发生进程调度是,进入执行状态,执行状态请求资源(好比IO操做)没法知足是发生阻塞,被丢入阻塞队列,当资源被知足时完成功能后进入就绪状态;
5. 核心态和用户态:核心态拥有搞特权,能够执行全部指令,访问全部寄存器和存储区;用户态低特权,只能访问部分存储区,执行部分指令。
6.建立:通常使用fork()函数建立子进程,要注意僵尸进程的出现,如何解决?在UNP中有说明:使用信号函数signal捕获SIGCHLD信号,使用相应函数处理(使用waitpid)。
7.线程:OS进行调度的基本单位,赞成进程内的全部县城共享进程的内存空间(资源),他们只拥有本身的程序计数器、栈和少许寄存器。
8. 建立:pthread_create(tid, 函数,参数)
9. 回收:其余线程使用pthread_join()来回收,或者在线程函数中设置线程脱离pthread_detach()使得执行完函数以后自行结束;
进程线程的不一样:
9.1. 调度的基本单位和资源分配的基本单位;
9.2. 是否拥有资源:进程拥有,线程只拥有少许寄存器和程序计数器还有栈;
9.3. 开销:建立开销,进程要涉及分配内存空间,因此要比线程慢,撤销也相似;特别的切换开销,进程的现场保护要比线程复杂,进程要切换内存空间,而后切换栈和相关寄存 器,而线程只须要后面的步骤,不须要切换内存空间,因此快。(UNP说线程建立可能要比进程快10~100倍)。
9.4. 通讯:进程间因为内存空间隔离,因此要跨内存空间来通讯(使用管道,消息队列,共享内存,信号量,socket套接字),而线程经过全局便来个就可进进行通讯。
9.5.适用场景:多线程适用于多机,而多线程适用于多核;
10.进程间通讯(IPC)
管道:匿名管道和命名管道,匿名管道只能用于具备亲缘关系的进程之间,而命名管道能够用于通常的进程之间;Linux头文件<pipe.h>
消息队列:建立消息队列,一个进程去读,另外一个去写;头文件:<mqueue.h>,mq_open()和mq_clos();
共享内存:最快的一种IPC方式,为何快?由于他直接将进程的进程空间映射到要使用的内存空间中,这样就避免了其余方式中的与内核缓冲区交互的时间开销。(其余的方式通常都是将设局写入进程缓冲区,然后进入内核缓冲区,而后另外一个进程再从内核缓冲区中将数据读到本身的进程缓冲区中)<sys/mman.h>
socket:一种能够实现远端进程通讯的一种方式。Linux头文件<sys/socket.h>
(TCP/UDP各有编程范式)
11.进程同步:
互斥锁:pthread_mutex_t,pthread_mutex_lock/trylock/unlock
读写锁:读锁和写锁,读锁共享,写锁互斥。和数据库的读写锁相似。
信号量:<semaphore.h>sem_open()/wait/trywait(),实例就是操做系统都作过的生产者消费者这问题
条件变量:pthread_cond_t signal()和wait()函数,一般和互斥量一块儿使用。
记录锁:对记录上锁,典型例子时文件锁。
12. 做业调度算法
12.1 先来先服务FCFS:就是先来的(在就绪队列头部的)先调度执行,后面的通通等着。(这让我想起了今早上宿舍中一舍友上厕所上了半个小时...我也很急,但又不能抢占资源...无奈的我只得寻找另外一台主机,成为他的一个临时进程)
12.2 短做业优先SJF:就是短的先执行。对长做业很是不友好,致使长做业“饥饿”。
12.3 优先级调度PSA:为做业肯定优先级,从后备队列中选取优先级高的装入内存。
12.4 高响应比优先:每次选取响应比较高的做业装入内存(响应比:(等待时间+运行时间)/等待时间),这种算法考虑了等待时间的因素。
13. 死锁
一组进程队列中,每一个进程都等待其余进程所持有的资源,形成循环等待的局面。
4个条件:互斥条件、请求与保持、不可剥夺、环路条件
如何预防:从234条件下手,请求须要先释放、能够高优先级剥夺、为每一类资源进行编号,请求高的须要先释放低的。
如何避免:银行家算法,搞清需求,进行预分配,判断是否能找到一个安全状态。
如何检测:资源分配图可否彻底化简;
如何解决:1.终止进程(所有终止;按照次序终止,直到死锁状态解除);2. 付出代价最小的解除算法
(这里我又想起了,InnoDB存储引擎处理死锁的方法:rollback持有最多互斥锁的事务)
14. 虚拟存储器
在我看来,虚拟存储器并未从实际上扩充物理内存。而是经过换页技术“看起来像是”扩充了物理内存。用到的原理涉及时间局部性和空间局部性。
在运行初始,只把必要的程序装入内存页,运行时若是发生缺页再进行缺页置换,置换的算法著名的有LRU(最近最少使用算法),原理是使用过的程序和数据,颇有可能会在一段时间后继续访问。
这样就能够将一个很是大的软件或程序运行起来,只不过是换页技术在其做用而已。
15. 物理内存与虚拟内存
物理内存对应于物理地址,虚拟内存对应于逻辑地址,它们之间存在一个映射关系。
1. CPU访问一个逻辑地址时,须要将逻辑地址分解成为一个组号和组内地址;根据组号去查地址转换表,肯定该组信息是否在内存中;
2. 若是该组号已经在内存(主存)中,那么从地址转换表中读出对应的物理组号;并根据物理组号和组内逻辑地址,存取必要的信息;
3. 若是该组号不在内存中,那么发生缺页中断,须要将存储在磁盘(辅存)上的信息读入内存中,若是有空闲页,直接读入,不然须要选定页置换出内存,再把须要的信息换入内存中,并更新地址转换表。
缺页置换的算法
1.随机算法:生成一个随机数,来肯定将那一页换出内存;
2.先进先出算法:将最早进入的页换出;
3.最近最少使用算法:替换最近最不常使用的页;LRU
4.最优算法:替换最长时间之后才使用的页面(一个理想算法)。
16。程序编译的过程
17.静态连接和动态连接的比较
1. 静态连接库须要装配入可执行文件中,而动态连接库不须要;
2. 静态连接库函数直接在可执行文件中你,因此执行速度快;而动态连接库,则是须要临时去库中寻找,因此执行速度稍慢;
3. 静态连接致使可执行文件臃肿,而使用动态连接库的可执行文件清爽,节约存储空间;
4. 此外静态连接库还存在重复装配的问题(#ifndef之流就是来解决他这类问题的),动态连接库不存在此问题;
5. 静态连接库更新和扩展麻烦(已经连接入可执行文件了),须要从新编译软件,而使用动态连接库,只须要替换动态连接库文件便可。
18.虚拟内存
操做系统对于内存(主存)的一种管理方式。操做系统给每个进程都分配地址空间,但此地址空间是虚拟内存空间,一般比其所对应的物理空间要大许多。
当CPU要访问某数据时,生成一个逻辑地址,而后用逻辑地址去查“页表”,页表上存储着全部存储在内存和磁盘上的数据的地址,页表每一条记录都至少有两个表项,一个是有效位,另外一个是物理地址或者是磁盘地址。若是发现有效位置1,那么证实数据在物理内存中(DRAM命中),根据另外一个表项上的物理地址去物理内存中查找读取便可。若是,有效位置0,那么数据不在物理内存上(未命中,发生缺页异常)。这时,须要将磁盘上的数据加载到物理内存中来。若是物理内存有空闲页,那么直接读进来便可,而后更新页表便可,而后从新查找页表,去读取须要的数据。若是,物理内存页都被占用,那么须要“页面置换”,采用“先进先出,LRU,理想方法”等方法能够将合适的页面调换出物理内存,而将磁盘上的数据页换到内存中来,一样更新页表,从新查找读取数据。
做用:内存管理和保护的工具 (PS CS:APP 《深刻理解计算机系统》 真的是一本奇书,NB!!!)
(图源Baidu)