1.进程和线程区别?
- 进程:资源分配的最小单位
- 线程:资源调度的最小单位
- 一个进程含有一个或者多个线程,线程共享进程的资源
- 进程的切换需要上下文的保存,因为涉及到TLB(快表)的销毁,所以开销比较大
- 线程的切换只需要少量的寄存器保存一下状态,如:程序计数器
2.为什么进程切换涉及到开销比较大?
- 每个进程都有自己的虚拟地址空间,即每个进程都有自己的页表,当进程切换后,页表也需要切换,页表切换后,TLB就失效了,所以Cache就降低了,所以在虚拟地址转换成物理地址的过程就变慢了。
3.进程间通信
匿名管道:只能兄弟进程或者父子进程之间通信
命名管道:在一个主机上的任意两个进程都可以进行通信,主要是以磁盘文件的方式存在
信号量:主要是在访问临界资源的时候,一个标志的作用
消息队列:解耦的,观察者、消费者、消息队列,消费者可以有选择的在消息队列中取出数据,但是要注意上一次如果消息没有消费完,可能会出现问题。
Socket:实现不同主机之间的通信(ip + 端口)
IPC/共享内存:由一个进程创建的一块内存,该内存可以由其他进程一起访问,但是要涉及到他们之间的一个访问安全。
4.进程/线程的同步方式
临界区:原子操作下,保证某一时刻只有一个线程能访问数据,其他线程来了就会被挂起。
互斥量:非常类似于临界区,只要状态0 和1,但是不同的是,互斥量不仅仅在同一程序中的不同线程;还可以应用于不同程序的线程之间。
信号量:互斥量是信号量的一个特殊例子,信号量允许多个线程访问临界资源。
Seamphore:acquire()、release()方法
事件:事件机制,允许一个线程处理完一个任务后,主动唤醒另外一个线程执行任务。
5.死锁以及死锁条件?
多个进程相互之间处于一种阻塞的状态,相互等待的状态。
条件:
1.互斥资源
2.不可剥夺
3.请求和保持
4.循环
死锁预防:
1.允许进程强行从占有者那取得资源
2.一次获取所有的资源。
3.按顺序执行相关的进程
死锁避免:
银行家算法:安全状态
如果对于当前进程所需要的资源存在分配,则认为是安全的,可以为其分配资源,反之,拒绝为进程分配资源,达到不安全状态
死锁解除
回滚操作,简单的终止一个或多个进程直到取消死锁为止。但是这样的话,一般消耗比较大,所以一般处理就是鸵鸟策略,不管就对了。
必先死锁的场景:
这里有一个线程A,按照先锁a再获得锁b的的顺序获得锁,而在此同时又有另外一个线程B,按照先锁b再锁a的顺序获得锁。
6.进程调度的策略
- FCFS:先来先服务
- SJT:短作业优先
- 时间片轮转:有个队列,时间片到了,然后回到队尾
- 优先级调度:给进程分配响应的优先级,进行优先级从高到低的处理
- 多级反馈序列:优先级+ 时间片轮转,每一个优先级下,时间片大小一样,随着优先级降低,时间片时间增大。
7.进程状态
8.分页
- 用户程序的地址空间被划分成若干固定大小的区域,称为 “页”,相应地,内存空间分成若干个物理块,页和块的大小相等。可将用户程序的任一页放在内存的任一块中,实现了离散分配。
逻辑地址-物理地址变换
假设一页的大小为4kb,如果逻辑地址为8203,那么:页号 = 8203 / 4096 = 2 -1 =1,页内偏移 = 8203 % 4096 = 11;
最后结果:物理地址 = 物理块号*页面大小 + 页内偏移量 = 6 * 4096 + 11 =28683
- 存在内部碎片
9.分段
- 段是按照程序的自然分界划分的长度可以动态改变的区域。通常,程序员把子程序、操作数和常数等不同类型的数据划分到不同的段中,并且每个程序可以有多个相同类型的段。
- 简单来说:就是把程序分段,大小可变,每个段都是有一定意义的,信息共享。
- 存在外部碎片
- 逻辑地址-物理地址变换
- 虚拟地址为2维的,分为段号 + 段内地址,根据段号获取基址,然后基址 +. 段内地址为内存空间的值。
10.段页
- 先分段,再分页
- 逻辑地址-物理地址变换
- 段号----页号 —块号 + 段内偏移量 = 物理地址
11.交换空间
- 当物理内存不足的时候,会把一些内存置换到磁盘上,而磁盘的这部分空间就叫做交换空间。
- 虚拟内存= 物理内存 +交换空间
12.虚拟内存
其实就是上面的原理,使得内存看起来非常大,有两个重要的局部性原理:
- 时间局部性:for循环
- 空间局部性 :数组
13.页面置换算法
- LRU(最近最久未使用)
- LFU(最近不常用)
- FIFO
- OPT
- 第二次机会算法(在FIFO的基础上,在置换出去的同时,先检查有没有使用,没有才置换)。
14.中断向量表
中断向量:中断程序的入口地址;
中断向量表:把系统中所有的中断类型码及其对应的中断向量按一定的规律存放在一个区域内,这个存储区域就叫中断向量表。
中断向量表就是一张表,表里的每一项是个指针,指针里存放着中断函数的地址。当发生相应的中断时,就会从表中根据中断向量号查找到相关函数的地址,从而跳转过去执行中断函数。