操作系统

1. 进程的有哪几种状态,及导致转换的事件。

基本状态:就绪,运行,阻塞。

就绪 执行 阻塞 
处于就绪状态的进程,当进程调度程序为之分配了处理机后,该进程便由就绪状态转变成执行状态。 
处于执行状态的进程在其执行过程中,因分配给它的一个时间片已用完而不得不让出处理机,于是进程从执行状态转变成就绪状态。 
正在执行的进程因等待某种事件发生而无法继续执行时,便从执行状态变成阻塞状态。

处于阻塞状态的进程,若其等待的事件已经发生,于是进程由阻塞状态转变为就绪状态。 


2. 进程与线程的区别。

a.地址空间和其它资源:进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见。一个进程崩溃后,在保护模式下不会对其它进程产生影响,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉。

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

c.调度和切换:线程上下文切换比进程上下文切换要快得多。


3. 进程通信的几种方式。

# 管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。

# 信号量( semophore ) : 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
# 消息队列( message queue ) : 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
# 信号 ( sinal ) : 信号是系统内核通知接收进程某个事件已经发生。
# 共享内存( shared memory ) :共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。
# 套接字( socket ) : 套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信。


4. 线程同步几种方式。(一定要会写生产者、消费者问题,完全消化理解)

①、 临界区(CCriticalSection)
当多个线程访问一个独占性共享资源时,可以使用临界区对象。拥有临界区的线程可以访问被保护起来的资源或代码段,其他线程若想访问,则被挂起,直到拥有临界区的线程放弃临界区为止。
②、 事件(CEvent)
一个线程在处理完一个任务后,主动唤醒另外一个线程执行任务。
③、 互斥量(CMutex)
互斥对象和临界区对象非常相似,只是其允许在进程间使用,而临界区只限制与同一进程的各个线程之间使用,但是更节省资源,更有效率。
④、 信号量(CSemphore)
 当需要一个计数器来限制可以使用某共享资源的线程数目时,可以使用“信号量”对象。CSemaphore类对象保存了对当前访问某一个指定资源的线程的计数值,该计数值是当前还可以使用该资源的线程数目。如果这个计数达到了零,则所有对这个CSemaphore类对象所控制的资源的访问尝试都被放入到一个队列中等待,直到超时或计数值不为零为止。

5. 线程的实现方式. (也就是用户线程与内核线程的区别)

用户线程指不需要内核支持而在用户程序中实现的线程,其不依赖于操作系统核心,应用进程利用线程库提供创建、同步、调度和管理线程的函数来控制用户线程。

内核线程由操作系统内核创建和撤销。内核维护进程及线程的上下文信息以及线程切换。一个内核线程由于I/O操作而阻塞,不会影响其它线程的运行。


6. 用户态和核心态的区别。

主要是特权级不同。内核态的优先级高。当CPU处于内核态,可以随意进入用户态;而当CPU处于用户态,只能通过中断和系统调用的方式进入内核态。

a. 系统调用

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

b. 异常

    当CPU在执行运行在用户态下的程序时,发生了某些事先不可知的异常,这时会触发由当前运行进程切换到处理此异常的内核相关程序中,也就转到了内核态,比如缺页异常。

c. 外围设备的中断

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

 

这3种方式是系统在运行时由用户态转到内核态的最主要方式,其中系统调用可以认为是用户进程主动发起的,异常和外围设备中断则是被动的。



8. 内存池、进程池、线程池。(c++程序员必须掌握)

池的方式实质上就是一个二级缓存概念,好处:

预先分配,先预分配好一定数量的对象,可以防止突然性的大并发请求,可以提升系统响应速度和负载能力。
缓存复用,使用完毕的对象可以暂时存储在池当中,以备被再利用。


9. 死锁的概念,导致死锁的原因.

系统资源不足,或者资源分配不当,引起各进程都无法继续运行下去


10. 导致死锁的四个必要条件。

(1) 互斥条件:一个资源每次只能被一个进程使用。
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。


13. 进程调度算法。(周转时间 =  程序结束时间 -- 开始服务时间、带权周转时间=  周转时间 /  要求服务时间)

①先来先服务调度算法(FCFS)
②短作业优先调度算法(SPF)
③最高优先级优先(HPF)
④时间片轮转(RR)


14. 内存管理的方式(页式、段式)

通过引入进程的逻辑地址,把进程地址空间与实际存储空间分离,增加存储管理的灵活性。地址空间和存储空间两个基本概念的定义如下:

地址空间:将源程序经过编译后得到的目标程序,存在于它所限定的地址范围内,这个范围称为地址空间。地址空间是逻辑地址的集合。

存储空间:指主存中一系列存储信息的物理单元的集合,这些单元的编号称为物理地址存储空间是物理地址的集合。

根据分配时所采用的基本单位不同,可将离散分配的管理方式分为以下三种:
页式存储管理、段式存储管理和段页式存储管理。其中段页式存储管理是前两种结合的产物。

①页式存储管理:

将程序的逻辑地址空间划分为固定大小的页(page),而物理内存划分为同样大小的页框(page frame)程序加载时,可将任意一页放人内存中任意一个页框,这些页框不必连续,从而实现了离散分配。

②段式存储管理

 在段式存储管理中,将程序的地址空间划分为若干个段(segment),这样每个进程有一个二维的地址空间。在前面所介绍的动态分区分配方式中,系统为整个进程分配一个连续的内存空间。而在段式存储管理系统中,则为每个段分配一个连续的分区,而进程中的各个段可以不连续地存放在内存的不同分区中。程序加载时,操作系统为所有段分配其所需内存,这些段不必连续,物理内存的管理采用动态分区的管理方法。

      在为某个段分配物理内存时,可以采用首先适配法、下次适配法、最佳适配法等方法。

      在回收某个段所占用的空间时,要注意将收回的空间与其相邻的空间合并。

      段式存储管理也需要硬件支持,实现逻辑地址到物理地址的映射。

      程序通过分段划分为多个模块,如代码段、数据段、共享段:

      –可以分别编写和编译
      –可以针对不同类型的段采取不同的保护
      –可以按段为单位来进行共享,包括通过动态链接进行代码共享

      这样做的优点是:可以分别编写和编译源程序的一个文件,并且可以针对不同类型的段采取不同的保护,也可以按段为单位来进行共享。

       总的来说,段式存储管理的优点是:没有内碎片,外碎片可以通过内存紧缩来消除;便于实现内存共享。缺点与页式存储管理的缺点相同,进程必须全部装入内存。


页式和段式系统有许多相似之处。比如,两者都采用离散分配方式,且都通过地址映射机构来实现地址变换。但概念上两者也有很多区别,主要表现在:

      1)、需求:是信息的物理单位,分页是为了实现离散分配方式,以减少内存的碎片,提高内存的利用率。或者说,分页仅仅是由于系统管理的需要,而不是用户的需要。段是信息的逻辑单位,它含有一组其意义相对完整的信息。分段的目的是为了更好地满足用户的需要。

    一条指令或一个操作数可能会跨越两个页的分界处,而不会跨越两个段的分界处。

     2)、大小:页大小固定且由系统决定,把逻辑地址划分为页号和页内地址两部分,是由机器硬件实现的。段的长度不固定,且决定于用户所编写的程序,通常由编译系统在对源程序进行编译时根据信息的性质来划分。

     3)、逻辑地址表示:页式系统地址空间是一维的,即单一的线性地址空间,程序员只需利用一个标识符,即可表示一个地址。分段的作业地址空间是二维的,程序员在标识一个地址时,既需给出段名,又需给出段内地址。



15. 内存连续分配方式采用的几种算法及各自优劣。

①单一连续分配
我们把内存分为系统内存区和用户区两部分,用户区分给单用户
②固定分区分配
把用户区提前分成固定大小的几个整体,每个程序使用一个整体
③动态分区分配
首次适应算法:在空闲内存中找到适合程序所需内存的第一块内存时,就给它分配所需内存大小,每次都是从空闲内存的开始查找;循环首次适应算法:从上次找到的空闲分区的下一个空闲分区开始找;最佳适应算法:把空闲内存中能够满足程序所需,又是最小的内存物理块时,就给它分配;最坏适应算法:从内存空闲中跳一个最大的空闲区分配给程序;快速适应算法:主要思想是,设置多个空闲分区链表,记录出每个独立内存块的信息,其中,把内存大小相同的记录在一个表中。
④动态重定位分区分配
把不同程序,且在内存中地址不连续的程序设法让他们连续。程序A、B,在内存中的位置不连续,即:A和B中间有空闲内存,我就把B和那部分的空闲区对换。必须把一个系统或用户程序装入一连续的内存空间。


16. 动态链接及静态链接.

如果编译器在编译时或链接时确定了所有函数的入口地址,那么这种确定地址的方法称为静态链接。

代码的装载速度快,执行速度也比较快,因为编译时它只会把你需要的那部分链接进去,应用程序相对比较大。但是如果多个应用程序使用的话,会被装载多次,浪费内存


如果是在运行时确定所有函数的入口地址,那么这种确定地址的方法称为动态链接。

多个应用程序可以使用同一个动态库,启动多个应用程序的时候,只需要将动态库加载到内存一次即可


17. 几种页面置换算法,会算所需换页数。(LRU用程序如何实现?)

先进先出置换算法(FIFO);最近最久未使用(LRU)算法


21. 虚拟内存的定义及实现方式。

它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。


22. 操作系统的四个特性。

并发;共享;虚拟;异步


23. DMA。

Direct Memory Access 直接存储器访问,允许不同速度的硬件装置来直接沟通,而不需要依于 CPU 


24. Spooling。

是为实现低速输入输出设备与高速的主机之间的高效率数据交换而设计的,中间建立一个缓冲区


阅读更多
个人分类: 基础知识
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭