操作系统思考与总结

Posted xidianzzh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了操作系统思考与总结相关的知识,希望对你有一定的参考价值。

1. 操作系统的四个特性

1并发:同一段时间内多个程序执行(注意区别并行和并发,前者是同一时刻的多个事件,后者是同一时间段内的多个事件)
2共享:系统中的资源可以被内存中多个并发执行的进线程共同使用
3虚拟:通过时分复用(如分时系统)以及空分复用(如虚拟内存)技术实现把一个物理实体虚拟为多个
4异步:系统中的进程是以走走停停的方式执行的,且以一种不可预知的速度推进

2.基本功能

1)进程管理 进程控制、进程同步、进程通信、死锁处理、处理机调度等。

2)内存管理 内存分配、地址映射、内存保护与共享、虚拟内存等。

3)文件管理 文件存储空间的管理、目录管理、文件读写管理和保护等。

4)设备管理 完成用户的 I/O 请求,方便用户使用各种设备,并提高设备的利用率。

   主要包括缓冲管理、设备分配、设备处理、虛拟设备等。

3.关于中断

什么是中断?

中断是指CPUI/O设备发来的中断信号的一种响应。CPU暂停正在执行的程序,保留CPU环境后,自动地去执行该I/O设备的中断处理程序。执行完后,再回到断点,继续执行原来的程序。I/O设备可以是字符设备,也可以是块设备、通信设备。由于中断时由外部设备引起的,故又称外中断。

 

硬件中断时通过中断请求线输入信号来请求处理机;软件中断是处理机内部识别并进行处理的中断过程。硬件中断一般是由中断控制器提供中断码类型,处理机自动转向中断处理程序;软件中断完全有处理机内部形成中断处理程序的入口地址并转向中断处理程序的入口地址,并转向中断处理程序,不需要外部提供信息。

 

外中断  CPU 执行指令以外的事件引起,如 I/O 完成中断,表示设备输入/输出处理已经完成,处理器能够发送下一个输入/输出请求。此外还有时钟中断、控制台中断等。

 

异常  CPU 执行指令的内部事件引起,如非法操作码、地址越界、算术溢出等。

 

陷入 另外一种由CPU内部事件所引起的中断,例如进程在运算中发生了上溢或者下溢,有如程序出错,如非法指令,地址越界等。通常把这类中断称为内中断或者陷入。若系统发现有陷入事件,CPU也将暂停正在执行的程序,转去执行该陷入事件的处理程序。中断和陷入的主要区别是信号的来源,是来自CPU外部,还是CPU内部。

 

中断处理流程?

1)测定是否有未响应的中断信号。

2)保护被中断进程的CPU环境。

3)转入相应的设备处理程序。

4)中断处理。

5)恢复CPU的现场并退出中断 中断的实时性是实时系统的一个重要方面。中断响应时间是影响中断实时性的主要因素。

4.进程与线程有什么区别?

1)进程 进程是资源分配的基本单位。 进程控制块 (Process Control BlockPCB) 描述进程的基本信息和运行状态,所谓的创建进程和撤销进程,都是指对 PCB 的操作。

 

2)线程 线程是独立调度的基本单位。 一个进程中可以有多个线程,它们共享进程资源。 QQ 和浏览器是两个进程,浏览器进程里面有很多线程,例如 HTTP 请求线程、事件响应线程、渲染线程等等,线程的并发执行使得在浏览器中点击一个新链接从而发起 HTTP 请求时,浏览器还可以响应用户的其它事件。

区别

(一)拥有资源

进程是资源分配的基本单位,但是线程不拥有资源,线程可以访问隶属进程的资源。

(二)调度

线程是独立调度的基本单位,在同一进程中,线程的切换不会引起进程切换,从一个进程内的线程切换到另一个进程中的线程时,会引起进程切换。

(三)系统开销

由于创建或撤销进程时,系统都要为之分配或回收资源,如内存空间、I/O 设备等,所付出的开销远大于创建或撤销线程时的开销。类似地,在进行进程切换时,涉及当前执行进程 CPU 环境的保存及新调度进程 CPU 环境的设置,而线程切换时只需保存和设置少量寄存器内容,开销很小。

(四)通信方面

进程间通信 (IPC) 需要进程同步和互斥手段的辅助,以保证数据的一致性。而线程间可以通过直接读/写同一进程中的数据段(如全局变量)来进行通信。

什么时候使用多进程模型,什么时候使用多线程模型

当在CPU-bound(计算密集型:绝大多数时间在计算) 时最好用 - 多进程,

而在 I/O bound(I/O密集型 : IO 处理 并且 大多时间是在等待) 的时候最好用 - 多线程。

 

进程结束后,进程的所有内存都将被释放,包括堆上的内存泄露的内存。

 

3)什么是协程?作用是什么?

协程,英文Coroutines,是一种比线程更加轻量级的存在。正如一个进程可以拥有多个线程一样,一个线程也可以拥有多个协程。 最重要的是,协程不是被操作系统内核所管理,而完全是由程序所控制(也就是在用户态执行)。 这样带来的好处就是性能得到了很大的提升,不会像线程切换那样消耗资源。其本质是用户空间下的线程。(即不存在上下文切换,用户与内核地址空间切换,但协程是在单线程中运行)

 

Go语言对协程的实现非常强大而简洁,可以轻松创建成百上千个协程并发执行。

Java语言并没有对协程的原生支持,但是某些开源框架模拟出了协程的功能

5.进程有哪几种状态?

一般来说,进程有三个状态,即就绪状态,运行状态,阻塞状态。

 

   运行态:进程占用CPU,并在CPU上运行;

   就绪态:进程已经具备运行条件,但是CPU还没有分配过来;

   阻塞态:进程因等待某件事发生而暂时不能运行;

 

6.进程调度|页面置换|磁盘调度有哪些?

6.1进程调度算法(CPU分配)(在就绪序列中怎么挑选进程让CPU执行)

先了解两个概念:

周转时间: 从开始申请执行任务,到执行任务完成

响应时间: 从开始申请执行任务到开始执行任务

 

1)先来先服务调度算法FCFS(即FIFIO):按作业或者进程到达的先后顺序依次调度;(平均周转时间可能会很长

2)短作业优先调度算法SJF:算法从就绪队列中选择估计时间最短的作业进行处理,直到得出结果或者无法继续执行(周转时间短,但是响应时间长)

3)时间片轮转调度RR:按到达的先后对进程放入队列中,然后给队首进程分配CPU时间片,时间片用完之后计时器发出中断,暂停当前进程并将其放到队列尾部,循环 ;(响应时间可以得到保证)

4)多级反馈队列调度算法:目前公认较好的调度算法;设置多个就绪队列并为每个队列设置不同的优先级,第一个队列优先级最高,其余依次递减。优先级越高的队列分配的时间片越短,进程到达之后按FCFS放入第一个队列,如果调度执行后没有完成,那么放到第二个队列尾部等待调度,如果第二次调度仍然没有完成,放入第三队列尾部。只有当前一个队列为空的时候才会去调度下一个队列的进程。

 

6.2页面置换算法

1)最佳置换算法(Optimal):一种理论的算法,选择淘汰的页面是以后一定不再使用的页面(理想化的),该算法无法实现,只能作为其他算法好坏的一个评价对比。

2)先进先出(FIFO)算法:总是最先淘汰最先进去的页面,该算法容易实现。缺点:通常程序调入内存的先后顺序和程序执行的先后顺序不一致,导致缺页率高。

3)最近最久未使用算法LRU:算法赋予每个页面一个访问字段,用来记录上次页面被访问到现在所经历的时间t,每次置换的时候把t值最大的页面置换出去(实现方面可以采用寄存器或者栈的方式实现)

4)时钟算法clock(也被称为是最近未使用算法NRU):页面设置一个访问位R,并将页面链接为一个环形队列,页面被访问的时候访问位设置R1。页面置换的时候,如果当前指针所指页面访问R0,那么置换,否则将其置为0,循环直到遇到一个访问为位0的页面。

 

但是这个方法有缺点:缺页比较少的时候(最近没有使用淘汰中的“最近”太长了),所有的R都为1(很少变成0,每次都要转一圈才能找到换出去的页,退化成FIFO,效率不高。

 

改进: 双指针,一个快,一个慢,像时钟一样 (定时清除R位)(更像clock

快时钟做R的清0定时清0,等到慢指针转到这里的时候R=0,说明在定时时间片内没有备访问,该页可以被替换了。

 

6.3磁盘调度

1)先来先服务(FCFS

2)最短寻道时间优先(SSTF):让离当前磁道最近的请求访问者启动磁盘驱动器,即是让查找时间最短的那个作业先执行,而不考虑请求访问者到来的先后次序,这样就克服了先来先服务调度算法中磁臂移动过大的问题

3)扫描算法(SCAN)或电梯调度算法:总是从磁臂当前位置开始,沿磁臂的移动方向去选择离当前磁臂最近的那个柱面的访问者。如果沿磁臂的方向无请求访问时,就改变磁臂的移动方向。在这种调度方法下磁臂的移动类似于电梯的调度,所以它也称为电梯调度算法。

4)循环扫描算法(CSCAN):循环扫描调度算法是在扫描算法的基础上改进的。磁臂改为单项移动,由外向里。当前位置开始沿磁臂的移动方向去选择离当前磁臂最近的哪个柱面的访问者。如果沿磁臂的方向无请求访问时,再回到最外,访问柱面号最小的作业请求。

 

7.进程同步有哪些方式?

1信号量

用于进程间传递信号的一个整数值。在信号量上只有三种操作可以进行:初始化,P操作和V操作,这三种操作都是原子操作。 P操作(递减操作)可以用于阻塞一个进程,V操作(增加操作)可以用于解除阻塞一个进程。

 

基本原理是两个或多个进程可以通过简单的信号进行合作,一个进程可以被迫在某一位置停止,直到它接收到一个特定的信号。该信号即为信号量s。 为通过信号量s传送信号,进程可执行原语semSignal(s);为通过信号量s接收信号,进程可执行原语semWait(s);如果相应的信号仍然没有发送,则进程被阻塞,直到发送完为止。 可把信号量视为一个具有整数值的变量,在它之上定义三个操作:

l 一个信号量可以初始化为非负数

l semWait操作使信号量s1.若值为负数,则执行semWait的进程被阻塞。否则进程继续执行。

l semSignal操作使信号量加1,若值大于或等于零,则被semWait操作阻塞的进程被解除阻塞。

 

2管程

管程是由一个或多个过程、一个初始化序列和局部数据组成的软件模块,其主要特点如下:

l 局部数据变量只能被管程的过程访问,任何外部过程都不能访问。

l 一个进程通过调用管程的一个过程进入管程。

l 在任何时候,只能有一个进程在管程中执行,调用管程的任何其他进程都被阻塞,以等待管程可用。管程通过使用条件变量提供对同步的支持,这些条件变量包含在管程中,并且只有在管程中才能被访问。有两个函数可以操作条件变量:

l cwait(c):调用进程的执行在条件c上阻塞,管程现在可被另一个进程使用。

l csignal(c):恢复执行在cwait之后因为某些条件而阻塞的进程。如果有多个这样的进程,选择其中一个;如果没有这样的进程,什么以不做。

 

3消息传递

消息传递的实际功能以一对原语的形式提供:

l send(destinationmessage)

l receive(sourcemessage)

这是进程间进程消息传递所需要的最小操作集。一个进程以消息的形式给另一个指定的目标进程发送消息;进程通过执行receive原语接收消息,receive原语中指明发送消息的源进程和消息。

4补充

PV操作由P操作原语和V操作原语组成(原语是不可中断的过程),对信号量进行操作,具体定义如下:

PS):将信号量S的值减1,即S=S-1

            ②如果S>=0,则该进程继续执行;否则该进程置为等待状态,排入等待队列。

VS):将信号量S的值加1,即S=S+1

            ②如果S>0,则该进程继续执行;否则释放队列中第一个等待信号量的进程。

PV操作的意义:

我们用信号量及PV操作来实现进程的同步和互斥。PV操作属于进程的低级通信。

交互的并发进程因为他们共享资源,一个进程运行时,经常会由于自身或外界的原因而被中端,且断点是不固定的。也就是说进程执行的相对速度不能由进程自己来控制,于是就会导致并发进程在共享资源的时出现与时间有关的错误。

临界区 :  我们把并发进程中与共享变量有关的程序段称为临界区。

  信号量S :  信号量的值与相应资源的使用情况有关。当它的值大于0时,表示当前可用资源的数量;当它的值小于0时,其绝对值表示等待使用该资源的进程个数。

进程的互斥是指当有若干个进程都要使用某一共享资源时,任何时刻最多只允许一个进程去使用该资源,其他要使用它的进程必须等待,直到该资源的占用者释放了该资源。 进程的同步是指在并发进程之间存在这一种制约关系,一个进程依赖另一个进程的消息,当一个进程没有得到另一个进程的消息时应等待,直到消息到达才被唤醒

5经典同步问题

 

l 生产者-消费者问题

l 哲学家就餐问题

l 读者-写者问题

6同步机制应遵循的规则

实际上,在对临界区资源进行管理的时候,可以将标志看做一个“锁”,“锁开”进入,“锁关”等待, 起初锁是打开的。每个要进入临界资源的进程必须先对锁进程测试,当锁未开时,则必须等待,直至锁被打开。反之,当锁是打开的,则应立即把锁锁上,以阻止其他进程进入临界区。显然,测试和关锁必须是连续的,不允许分开执行。

9. 进程通信的方式?

进程同步与进程通信很容易混淆,它们的区别在于:

  • 进程同步:控制多个进程按一定顺序执行;
  • 进程通信:进程间传输信息。

进程通信是一种手段,而进程同步是一种目的。也可以说,为了能够达到进程同步的目的,需要让进程进行通信,传输一些进程同步所需要的信息。

 

一、管道

管道,通常指无名管道,是 UNIX 系统IPC最古老的形式。

l 它是半双工的(即数据只能在一个方向上流动),具有固定的读端和写端。

l 它只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间)。

l 它可以看成是一种特殊的文件,对于它的读写也可以使用普通的readwrite 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。

二、FIFO

也称为命名管道,它是一种文件类型。

l FIFO可以在无关的进程之间交换数据,与无名管道不同。

l FIFO有路径名与之相关联,它以一种形式存在于文件系统中。

三、消息队列

是消息的链接表,存放在内核中。一个消息队列由一个标识符(即队列ID)来标识。

l 消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级。

l 消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除。

l 消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取。

四、信号量(semaphore

与已经介绍过的 IPC 结构不同,它是一个计数器。信号量用于实现进程间的互斥与同步,而不是用于存储进程间通信数据。

l 信号量用于进程间同步,若要在进程间传递数据需要结合共享内存。

l 信号量基于操作系统的 PV 操作,程序对信号量的操作都是原子操作。

l 每次对信号量的 PV 操作不仅限于对信号量值加 1 或减 1,可以加减任意正整数。

l 支持信号量组。

五、共享内存(Shared Memory

指两个或多个进程共享一个给定的存储区。

l 共享内存是最快的一种 IPC,因为进程是直接对内存进行存取。

l 因为多个进程可以同时操作,所以需要进行同步。

l 信号量+共享内存通常结合在一起使用,信号量用来同步对共享内存的访问。

 

五种通讯方式总结

  1. 管道:速度慢,容量有限,只有父子进程能通讯
  2. FIFO:任何进程间都能通讯,但速度慢,去除了管道只能在父子进程中使用的限制
  3. 消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题
  4. 信号量:不能传递复杂消息,只能用来同步
  5. 共享内存区:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一个进程要注意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以用作线程间通讯,不过没这个必要,线程间本来就已经共享了同一进程内的一块内存

补:套接字

与其它通信机制不同的是,它可用于不同机器间的进程通信。

9.死锁产生的条件,怎么解决?

PS:数据库和操作系统本质均相同

1) 产生死锁的四个必要条件

互斥条件:一个资源每次只能被一个进程使用。

请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。

循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。

2) 死锁的处理方法

预防死锁:破坏产生死锁的4个必要条件中的一个或者多个;实现起来比较简单,但是如果限制过于严格会降低系统资源利用率以及吞吐量

 

避免死锁:在资源的动态分配中,防止系统进入不安全状态(可能产生死锁的状态)-银行家算法

 

检测死锁:允许系统运行过程中产生死锁,在死锁发生之后,采用一定的算法进行检测,并确定与死锁相关的资源和进程,采取相关方法清除检测到的死锁。实现难度大

 

死锁恢复:利用抢占恢复;利用回滚恢复;通过杀死进程恢复

 

死锁忽略: windowsLinux个人版都不做死锁处理,直接忽略,大不了重启就好了,小概率事件,代价可以接受

 

银行家算法

我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。 为保证资金的安全,银行家规定:

1) 当一个顾客对资金的最大需求量不超过银行家现有的资金时就可接纳该顾客;

2) 顾客可以分期贷款,但贷款的总数不能超过最大需求量;

3) 当银行家现有的资金不能满足顾客尚需的贷款数额时,对顾客的贷款可推迟支付,但总能使顾客在有限的时间里得到贷款;

4) 当顾客得到所需的全部资金后,一定能在有限的时间里归还所有的资金. 操作系统按照银行家制定的规则为进程分配资源,当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配。当进程在执行中继续申请资源时,先测试该进程本次申请的资源数是否超过了该资源所剩余的总量。若超过则拒绝分配资源,若能满足则按当前的申请量分配资源,否则也要推迟分配。

示例:https://www.cnblogs.com/chuxiuhong/p/6103928.html

 

内存管理:https://www.cnblogs.com/xdyixia/p/9274909.html

10  互斥量和信号量的区别

1. 互斥量用于线程的互斥,信号量用于线程的同步。

这是互斥量和信号量的根本区别,也就是互斥和同步之间的区别。

互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。

同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源

2. 互斥量值只能为0/1,信号量值可以为非负整数。

也就是说,一个互斥量只能用于一个资源的互斥访问,它不能实现多个资源的多线程互斥问题。信号量可以实现多个同类资源的多线程互斥和同步。当信号量为单值信号量是,也可以完成一个资源的互斥访问。

  1. 互斥量的加锁和解锁必须由同一线程分别对应使用,信号量可以由一个线程释放,另一个线程得到。

信号量用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作(大家都在semtake的时候,就阻塞在 哪里)。而互斥锁是用在多线程多任务互斥的,一个线程占用了某一个资源,那么别的线程就无法访问,直到这个线程unlock,其他的线程才开始可以利用这 个资源。比如对全局变量的访问,有时要加锁,操作完了,在解锁。有的时候锁和信号量会同时使用的
也就是说,信号量不一定是锁定某一个资源,而是流程上的概念,比如:有A,B两个线程,B线程要等A线程完成某一任务以后再进行自己下面的步骤,这个任务 并不一定是锁定某一资源,还可以是进行一些计算或者数据处理之类。而线程互斥量则是锁住某一资源的概念,在锁定期间内,其他线程无法对被保护的数据进 行操作。在有些情况下两者可以互换。

两者之间的区别:

作用域
信号量: 进程间或线程间(linux仅线程间的无名信号量pthread semaphore)
互斥锁: 线程间

上锁时 
信号量: 只要信号量的value大于0,其他线程就可以sem_wait成功,成功后信号量的value减一。若value值不大于0,则sem_wait使得线程阻塞,直到sem_post释放后value值加一,但是sem_wait返回之前还是会将此value值减一
互斥锁: 只要被锁住,其他任何线程都不可以访问被保护的资源

 

11 段页式内存管理的概念

  页式存储管理能有效地提高内存利用率,而分段存储管理能反映程序的逻辑结构并有利于段的共享。如果将这两种存储管理方法结合起来,就形成了段页式存储管理方式。

  段页式管理就是将程序分为多个逻辑段,在每个段里面又进行分页,即将分段和分页组合起来使用。这样做的目的就是想同时获得分段和分页的好处,但又避免了单独分段或单独分页的缺陷。

  如果我们将每个段看做一个单独的程序,则逻辑分段就相当于同时加载多个程序。

 

二、段页式内存管理的实现

  在段页式系统中,作业的逻辑地址分为三部分:段号、页号和页内偏移量,如图所示。

  为了实现地址变换,系统为每个进程建立一张段表,而每个分段有一张页表(在一个进程中,段表只有一个,而页表可能有多个)。段表表项中至少包括段号、页表长度和页表起始地址,页表表项中至少包括页号和块号。此外,系统中还应有一个段表寄存器,指出作业的段表起始地址和段表长度。

  在进行地址变换时,首先通过段表查到页表起始地址,然后通过页表找到页帧号,最后形成物理地址。如图所示,进行一次访问实际需要三次访问主存,这里同样可以使用快表以加快查找速度,其关键字由段号、页号组成,值是对应的页帧号和保护码。

12 用户态和内核态的区别

在计算机系统中,通常运行着两类程序:系统程序和应用程序,为了保证系统程序不被应用程序有意或无意地破坏,为计算机设置了两种状态:

 

系统态(也称为管态或核心态),操作系统在系统态运行——运行操作系统程序

用户态(也称为目态),应用程序只能在用户态运行——运行用户程序

在实际运行过程中,处理机会在系统态和用户态间切换。相应地,现代多数操作系统将 CPU 的指令集分为特权指令和非特权指令两类。

 

 

1) 特权指令——在系统态时运行的指令

 

对内存空间的访问范围基本不受限制,不仅能访问用户存储空间,也能访问系统存储空间,

特权指令只允许操作系统使用,不允许应用程序使用,否则会引起系统混乱。

 

 

2) 非特权指令——在用户态时运行的指令

 

一般应用程序所使用的都是非特权指令,它只能完成一般性的操作和任务,不能对系统中的硬件和软件直接进行访问,其对内存的访问范围也局限于用户空间。

 

UNIX 系统把进程的执行状态分为两种:

 

一种是用户态执行,表示进程正处于用户状态中执行;

另一种是核心态执行,表示一个应用进程执行系统调用后,或 I/O 中断、时钟中断后,进程便处于核心态执行。

这两种状态的主要差别在于:

 

处于用户态执行时,进程所能访问的内存空间和对象受到限制,其所占有的处理机是可被抢占的;

而处于核心态执行中的进程,则能访问所有的内存空间和对象,且所占用的处理机是不允许被抢占的。

 

 

 

用户态切换到内核态的唯一途径——>中断/异常/陷入

内核态切换到用户态的途径——>设置程序状态字

 

 

注意一条特殊的指令——陷入指令(又称为访管指令,因为内核态也被称为管理态,访管就是访问管理态)

 

该指令给用户提供接口,用于调用操作系统的服务。

用户态和内核态的切换

 

当在系统中执行一个程序时,大部分时间是运行在用户态下的,在其需要操作系统帮助完成一些用户态自己没有特权和能力完成的操作时就会切换到内核态。

 

用户态切换到内核态的3种方式

 

1)系统调用

 

这是用户态进程主动要求切换到内核态的一种方式。用户态进程通过系统调用申请使用操作系统提供的服务程序完成工作。例如fork()就是执行了一个创建新进程的系统调用。系统调用的机制和新是使用了操作系统为用户特别开放的一个中断来实现,如Linuxint 80h中断。

 

2)异常

 

cpu在执行运行在用户态下的程序时,发生了一些没有预知的异常,这时会触发由当前运行进程切换到处理此异常的内核相关进程中,也就是切换到了内核态,如缺页异常。

 

3)外围设备的中断

 

当外围设备完成用户请求的操作后,会向CPU发出相应的中断信号,这时CPU会暂停执行下一条即将要执行的指令而转到与中断信号对应的处理程序去执行,如果前面执行的指令时用户态下的程序,那么转换的过程自然就会是 由用户态到内核态的切换。如硬盘读写操作完成,系统会切换到硬盘读写的中断处理程序中执行后边的操作等。

 

这三种方式是系统在运行时由用户态切换到内核态的最主要方式,其中系统调用可以认为是用户进程主动发起的,异常和外围设备中断则是被动的。从触发方式上看,切换方式都不一样,但从最终实际完成由用户态到内核态的切换操作来看,步骤有事一样的,都相当于执行了一个中断响应的过程。系统调用实际上最终是中断机制实现的,而异常和中断的处理机制基本一致。

 

5、用户态到内核态具体的切换步骤:

 

1)从当前进程的描述符中提取其内核栈的ss0esp0信息。

 

2)使用ss0esp0指向的内核栈将当前进程的cs,eip,eflags,ss,esp信息保存起来,这个过程也完成了由用户栈到内核栈的切换过程,同时保存了被暂停执行的程序的下一条指令。

 

3)将先前由中断向量检索得到的中断处理程序的cs,eip信息装入相应的寄存器,开始执行中断处理程序,这时就转到了内核态的程序执行了。

13 你知道为啥一个应用有4G,但是机器内存只有2G,为啥这个应用可以跑起来?原理是啥?详细谈谈其机制。

如果很卡但是可以运行也叫跑起来,那是没什么太大问题的,因为电脑只会把当前急需的资源调到内存里,内存不够的时候,一些不急需的资源会被放进磁盘,所以即使你电脑只有4G内存,大部分游戏也可以运行,只是你可以接受ppt

根据你的情况,我是建议你升级内存或使用该软件的历史版本

电脑自己的windows运行也是需要并且需要很多内存的,所以你可以支配的内存远小于4G

14经典同步问题

生产者和消费者问题前面已经讨论过了。

15 哲学家进餐问题

 

 

 

五个哲学家围着一张圆桌,每个哲学家面前放着食物。哲学家的生活有两种交替活动:吃饭以及思考。当一个哲学家吃饭时,需要先拿起自己左右两边的两根筷子,并且一次只能拿起一根筷子。

下面是一种错误的解法,考虑到如果所有哲学家同时拿起左手边的筷子,那么就无法拿起右手边的筷子,造成死锁。

为了防止死锁的发生,可以设置两个条件:

  • 必须同时拿起左右两根筷子;
  • 只有在两个邻居都没有进餐的情况下才允许进餐。

16 linux内存模型

 

17 孤儿进程与僵尸进程

我们知道在unix/linux中,正常情况下,子进程是通过父进程创建的,子进程在创建新的进程。子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程 到底什么时候结束。 当一个 进程完成它的工作终止之后,它的父进程需要调用wait()或者waitpid()系统调用取得子进程的终止状态。

什么是孤儿进程

孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。

什么是僵尸进程

  僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用waitwaitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。

问题及危害

  unix提供了一种机制可以保证只要父进程想知道子进程结束时的状态信息, 就可以得到。这种机制就是: 在每个进程退出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存等。 但是仍然为其保留一定的信息(包括进程号the process ID,退出状态the termination status of the process,运行时间the amount of CPU time taken by the process等)。直到父进程通过wait / waitpid来取时才释放。 但这样就导致了问题,如果进程不调用wait / waitpid的话, 那么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程. 此即为僵尸进程的危害,应当避免。

  孤儿进程是没有父进程的进程,孤儿进程这个重任就落到了init进程身上init进程就好像是一个民政局,专门负责处理孤儿进程的善后工作。每当出现一个孤儿进程的时候,内核就把孤 儿进程的父进程设置为init,而init进程会循环地wait()它的已经退出的子进程。这样,当一个孤儿进程凄凉地结束了其生命周期的时候,init进程就会代表党和政府出面处理它的一切善后工作。因此孤儿进程并不会有什么危害。

  任何一个子进程(init除外)在exit()之后,并非马上就消失掉,而是留下一个称为僵尸进程(Zombie)的数据结构,等待父进程处理。这是每个 子进程在结束时都要经过的阶段。如果子进程在exit()之后,父进程没有来得及处理,这时用ps命令就能看到子进程的状态是“Z”。如果父进程能及时 处理,可能用ps命令就来不及看到子进程的僵尸状态,但这并不等于子进程不经过僵尸状态。  如果父进程在子进程结束之前退出,则子进程将由init接管。init将会以父进程的身份对僵尸状态的子进程进行处理。

  僵尸进程危害场景:

  例如有个进程,它定期的产 生一个子进程,这个子进程需要做的事情很少,做完它该做的事情之后就退出了,因此这个子进程的生命周期很短,但是,父进程只管生成新的子进程,至于子进程 退出之后的事情,则一概不闻不问,这样,系统运行上一段时间之后,系统中就会存在很多的僵死进程,倘若用ps命令查看的话,就会看到很多状态为Z的进程。 严格地来说,僵死进程并不是问题的根源,罪魁祸首是产生出大量僵死进程的那个父进程。因此,当我们寻求如何消灭系统中大量的僵死进程时,答案就是把产生大 量僵死进程的那个元凶枪毙掉(也就是通过kill发送SIGTERM或者SIGKILL信号啦)。枪毙了元凶进程之后,它产生的僵死进程就变成了孤儿进 程,这些孤儿进程会被init进程接管,init进程会wait()这些孤儿进程,释放它们占用的系统进程表中的资源,这样,这些已经僵死的孤儿进程 就能瞑目而去了。

18 知道程序局部性原理吗?

程序bai局部性原理,是指程序在执du行时呈现出局部性规律,即在一段时间内,zhi整个程序的执行仅dao限于程序中的某一部分。相应地,执行所访问的存储空间也局限于某个内存区域。

 

程序局部性包括程序的时间局部性和程序的空间局部性。

 

1、程序的时间局部性:  是指程序即将用到的信息可能就是目前正在使用的信息。

 

2、程序的空间局部性:  是指程序即将用到的信息可能与目前正在使用的信息在空间上相邻或者临近。

以上是关于操作系统思考与总结的主要内容,如果未能解决你的问题,请参考以下文章

高并发秒杀系统--课程总结与思考

分布式系统中生成全局ID的总结与思考

从银行转账失败到分布式事务:总结与思考

移动端中的“加载策略”思考与总结

BFS实现8数码问题,思考与总结

前端DDD总结与思考