1.进程、线程
1.简单说一下并发和并行的理解?
并行:指多个任务可以同时运行。
并发:指通过上下文快速切换,使得多个线程看上去像在同时运行。
2.同步、异步、阻塞、非阻塞的概念
1.同步和异步关注的是消息通信机制。
- 同步:当一个同步调用发出后,调用者要一直等待返回结果,没得到结果,调用就不返回。
- 异步:当一个异步调用发出后,调用者不能立刻得到返回结果,但还是直接返回;被调用者通过状态、通知来通知调用者。
2.阻塞、非阻塞关注的是程序在等待调用结果时的状态。
- 阻塞:调用结果返回前,当前线程会被挂起;
- 非阻塞:调用结果返回前,该调用不会阻塞当前线程
3.什么是进程?什么是线程?
3.1.进程就是正在执行的程序实例。
它由操作系统进行管理,操作系统会为每个进程分配时间来占用CPU,操作系统还会为每个进程分配特定的资源。
操作系统为了跟踪每个进程的活动状态,维护了一个进程表,在进程表的内部,列出了每个进程的状态以及每个进程使用的资源等。
3.2.线程是进程的一个实体,有时也被成为轻量级线程。
线程是CPU调度和分派的基本单位,他是比进程更小的能独立运行的基本单位。
4.进程和线程的区别
进程 | 线程 |
---|---|
资源分配的基本单位 | CPU调度的基本单位 |
进程的创建、撤销,系统都要为之分配、回收资源;开销比较大 | 创建、撤销线程则相对来说开销要小 |
不同进程之间内存相互独立 | 同一进程内的多个线程共享内存,不同进程的线程之间不可见 |
进程之间相互不影响 | 一个线程挂掉可能导致整个进程都挂掉 |
5.为什么有了进程,还要有线程呢?
进程可以使多个程序并发执行,以提高资源的利用率和系统的吞吐量。但也有如下缺点:
- 1.进程在同一时间只能干一件事;
- 2.进程在执行过程中阻塞,整个进程就会被挂起,即使进程中有些工作不依赖需要等待的资源,也不会执行。
基于以上缺点,操作系统引入了比进程粒度更小的线程,作为并发执行的基本单位,从而减少程序在并发执行时所付出的时间和空间开销,提升并发性能。
6.为什么进程切换开销比线程大?——进程和线程切换的开销
进程切换开销 | 线程切换开销 |
---|---|
切换CPU上下文 | 切换CPU上下文 |
切换内核栈 | 切换内核栈 |
切换虚拟地址空间 | \ |
1.进程切换会慢,TLB快表失效
页表的查找是一个很慢的过程,所以会用TLB快表来缓存页地址,来加速页表的查找。
- 1.进程切换后,页表也要切换,所以TLB也会失效,所以此时虚拟地址转换为物理地址就变的很慢,表出来程序卡顿。
- 2.线程切换,并不需要切换页表。
2.切换CPU上下文(进程上下文切换、线程上下文切换、中断上下文切换)
- 1.保存寄存器中的内容(进程、线程)
- 2.CPU高速缓存失效(进程、线程)
- 3.TLB快表失效(进程)
3.切换内核线
用户态——>内核态——>用户态
6.进程的状态切换——就绪、运行、阻塞之间的切换
1.就绪 —> 执⾏
2.执⾏ —> 阻塞
3.阻塞 —> 就绪
4.执⾏ —> 就绪
7.进程间通信方式——管道、消息队列、信号量、共享内存
7.1.管道
无名管道(pip) | 命名管道(FIFO) |
---|---|
半双工的,具有固定的读端和写端。 | 半双工 |
只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间) | 可以在无关的进程之间交换数据 |
可以看成是一种特殊的文件,对于它的读写也可以使用普通的read、write 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。 | FIFO有路径名与之相关联,它以一种特殊设备文件形式存在于文件系统中。 |
1.它是半双⼯的,具有固定的读端和写端;若要实现双向同时通信,就要设置2个管道;
2.它只能⽤于⽗⼦进程或者兄弟进程之间的进程的通信;
3.各进程要互斥的访问管道;
4.如果没写满,就不允许读,如果没读空,就不允许写;
5.数据一旦读出,就从管道被抛弃,就意味着读进程最多只能有1个,否则可能被读错;
7.2.消息队列(eg.电子邮件系统,基于间接通信方式)
1.它是消息的链接表,存放在内核中。一个消息队列由一个标识符ID来标识;
2.它是面向记录的,其中的消息有特定的格式以及特定的优先级;
3.消息队列独立于发送和接收进程。进程终止,消息队列及其内容并不会被删除;
4.消息队列可以实现对消息的随机查询,也可以按类型查询;
7.3.信号量(P:-1,请求1个资源,V:+1,释放1个资源)
1.信号量是一个计数器,用于实现进程间的互斥与同步,而不是存储进程间的通信数据;
2.用于进程间同步,若要传递数据需要结合共享内存;
3.基于操作系统的PV操作,程序对信号量的操作都是原子操作;PV操作不仅限于加1、减1,可以加减任意正整数;
4.支持信号量组。
7.4.共享存储——基于数据结构、基于存储区,2种
1.共享存储,指的是多个进程共享一个指定的存储区;
2.他是最快的IPC,因为进程直接对内存进行存取;
8.进程调度的时机
1.主动放弃
- 进程正常终止
- 进程发生异常而终止
- 主动阻塞(eg:IO等待)
2.被动放弃
- 分给的时间片用完;
- 有更紧急的事情要处理(eg:IO中断)
- 有更高级的进程进入就绪队列
9.进程的调度算法:FIFO、时间片轮转、短作业优先、优先级调度、⾼响应⽐优先
10.什么时候不能进行进程调度?
- 1.处理中断时;
- 2.进程在操作系统内核程序临界区时
- 3.原子操作中
2.死锁
11.什么是死锁?
由于系统存在一些不可剥夺的资源,而当2个或多个进程占有自身资源,并请求对方资源时,会导致每个进程都无法推进,这就是死锁。
12.产生死锁的原因?
1.资源竞争(不可剥夺资源)
2.进程推进顺序不当
13.死锁产生的必要条件?
1.互斥条件
进程要求对所分配的资源进行排他性控制。
2.请求和保持
当进程因请求资源而阻塞时,对以获得的资源保持不放。
3.资源不可剥夺
进程已获得的资源在未使用完之前,不能剥夺,只能在使用完时由自己释放。
4.形成环路等待
发生死锁时,必然存在一个进程-资源的环形链。
14.解决死锁的基本方法?
- 1.预防死锁
- 2.避免死锁
- 3.检测死锁
- 4.解除死锁
15.怎么预防死锁?
1.破坏不可剥夺条件
当进程获得了部分资源,但得不到其他资源时,则释放已占有资源。
2.破坏环路等待条件
给资源进行编号,每个进程按编号递增的顺序请求资源,释放则相反。
16.怎么避免死锁
17.怎么解除死锁?
1.资源剥夺。
挂起死锁线程,并抢占它的资源,资源分配给其他死锁线程;
2.撤销进程
强制撤销部分、甚至全部死锁进程并剥夺这些进程的**资源(**撤销原则,可以按进程优先级进行)
3.进程回退
让一个或者多个进程回退到足以避免死锁的地步。进程回退时自愿释放资源,而不是被剥夺。(系统要保持进程的历史信息,设置还原点)
3.内存管理
18.物理地址、逻辑地址、虚拟内存的概念
1.物理地址:它是地址转换的最终地址,进程在运行时执行指令和访问数据都要通过物理地址从主存中存取,是内存单元真正的地址。
2.逻辑地址:计算机用户看到的地址,长度为10的整型数组,操作系统返回首个元素的内存地址,整型int大小为4字节,所以第2个元素的地址为起始地址+4,以此类推。
3.虚拟内存:计算机内存管理的一种技术。它使得应用程序认为他有连续的可用的内存;但实际上,它通常是被分割成多个物理碎片,还有多个部分暂存在外部磁盘上,在需要时进行数据交换。(页面置换)
19.分页与分段的区别?
分段 | 分页 |
---|---|
信息的逻辑单位,它是根据⽤户的需要划分的,段对⽤户是可⻅的 | 信息的物理单位,是为了管理主存的⽅便⽽划分的,对⽤户是透明的; |
⼤⼩不固定,由它所完成的功能决定 | ⼤⼩固定,由系统决定 |
段向⽤户提供⼆维地址空间 | ⻚向⽤户提供的是⼀维地址空间 |
段是信息的逻辑单位,便于存储保护 和 信息的共享 | ⻚的保护和共享受到限制 |
20.为什么可以用虚拟内存?——局部性原理、页面置换、最终假象
1.基于局部性原理
在程序装入时,可以将程序很快用到的部分装入内存,暂时用不到的留在外存,就可以让程序运行。
- 时间局部性:当前时刻被引用过一次的存储器位置在未来时刻会被多次引用;
- 空间局部性:如果一个存储器的位置被引用,那么将来他附近的位置也会被引用。
2.页面置换
当程序所访问的部分不在内存时,由操作系统负责从外存调入内存。若内存空间不够,由操作系统负责将内存中暂时不用的信息换出到外存。
3.虚拟内存造成的假象
在操作系统的管理下,用户看来似乎有一个比实际大的多的内存。
21.如何实现虚拟内存?(虚拟内存的管理)——分段、分页、段页式
虚拟内存通过内存管理单元映射到物理内存;
内存管理单元保存
1.内存分段——段选择因子(段表的索引)、段内偏移量
虚拟地址通过段表与物理地址进行映射。
分段管理的缺点:
- 1.会产生内存碎片
- 外部内存碎片:产生多个不连续的小物理内存,导致新的程序无法加载进来。
- 内部内存碎片:程序所有的内存都被加载进物理内存,但是此程序并非所有的部分被经常用到。
- 2.内存交换效率低
- 为了消除多个不连续的小物理内存,就要进行内存交换,让程序重新加载到物理内存的新位置,以获得连续的物理内存。
- 这种做法就会导致频繁的内存交换,会导致卡顿。
2.内存分页 (虚拟地址:页号+页内偏移量)
虚拟内存通过页表与物理地址进行映射。把整个虚拟内存和物理内存切成一段段固定大小的空间,称为:页。Linux下,每页4kb。
一般虚拟地址 = 页号 + 页内偏移量。
- 用页号在页表内找到物理页号
- 物理页号 + 页内偏移量 找到资源。
1.页表:它必须覆盖所有虚拟内存,否则计算机就不工作了,所以进程太多会导致查找效率低 - 存在内存管理单元(MMU)中;
- 页表会产生缺页中断,在内核态进行进程页表,再返回用户态空间,恢复进程的运行。
2.页表太大,导致效率低怎么办?——多级索引(类似B+树)
二级虚拟地址 = 一级页号 + 二级页号 + 页内偏移
- 1.通过一级页号找到二级页表的地址
- 2.用二级页表的地址找到二级页表,并用二级页号找到该表中的物理页号;
- 3.物理页号 + 页内偏移量,找到资源
3.段页式
20.页面置换算法有哪些?FIFO、LRU、时钟置换算法
简单时钟置换算法:
21.页面抖动
1.什么是抖动?
1.刚换出的页面立马又要被换入内存;
2.刚刚换入的又要被换出。
2.原因
1.为进程分配的物理内存太少
- 但是分配物理内存太多,又会降低系统并发度
2.页面置换算法有问题
22.什么是缓冲区溢出?有什么危害?
缓冲区:是暂时存放输入输出数据的内存;
缓冲区溢出:指的是计算机向缓冲区填充数据时超出了缓冲区本身的容量,导致覆盖掉了合法数据。
危害:程序崩溃导致拒绝服务、跳转执行一段恶意代码。
23.谈谈你对动态链接库、静态链接库的理解?
静态链接
就是在编译链接时直接将需要的执⾏代码拷⻉到调⽤处,优点就是在程序发布的时候就不需要依赖的库,也就是不再需要带着库⼀块发布,程序可以独⽴执⾏,但是体积可能会相对⼤⼀些。
动态链接
就是在编译的时候不直接拷⻉可执⾏代码,⽽是通过记录⼀系列符号和参数,在程序运⾏或加载时将这些信息传递给操作系统,操作系统负责将需要的动态库加载到内存中,然后程序在运⾏到指定的代码时,去共享执⾏内存中已经加载的动态库可执⾏代码,最终达到运⾏时连接的⽬的。优点是多个程序可以共享同⼀段代码,⽽不需要在磁盘上存储多个拷⻉,缺点是由于是运⾏时加载,可能会影响程序的前期执⾏性能