操作系统知识点整理

2023-05-16

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

进程的状态:运行、阻塞、就绪三种状态。

进程状态转换图

运行和就绪之间的转换由调度程序引导;
当进程等待一个外部事件发生时,则由执行→阻塞;
当等待的一个外部事件发生时,则阻塞→就绪;
当没有其他进程运行,则立刻由就绪→执行;否则处于就绪态,等待CPU空闲并轮到它运行。


2. 进程与线程的区别

  • 地址空间:进程中线程共享进程的地址空间;而进程有自己的地址空间。
  • 资源拥有:进程是资源分配和拥有的单位;而同一进程中的线程共享进程的资源。(各线程有自己的程序计数器、寄存器、堆栈、状态)
  • 进程是资源分配的基本单位;线程是处理器调度的基本单位。

为什么要引入线程?

进程是资源拥有者。在创建、切换和撤销的操作需要较大的时空开销,限制了并发程度的进一步提高。引入线程将进程作为资源分配单位和资源调度单位这两个属性分开处理。进程任作为资源分配的基本单位;把调度执行和切换的任务交给线程。


3. 进程通信的几种方式

  • 管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。有名管道(named pipe)也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
  • 信号量( semophore ):信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
  • 消息队列( message queue ):消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
  • 信号( signal ):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数)。
  • 共享内存( shared memory ):共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。
  • 套接字( socket ):套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。

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

  • 互斥锁:
    提供对临界资源的保护,当多线程试图访问临界资源时,都必须通过获取锁的方式来访问临界资源。(临界资源:是被多线程共享的资源)
    1. 初始化锁。在Linux下,线程的互斥量数据类型是pthread_mutex_t。在使用前,要对它进行初始化。
    2. 加锁。对共享资源的访问,要对互斥量进行加锁,如果互斥量已经上了锁,调用线程会阻塞,直到互斥量被解锁。
    3. 解锁。在完成了对共享资源的访问后,要对互斥量进行解锁。
    4. 销毁锁。锁在是使用完成后,需要进行销毁以释放资源。
  • 条件变量:提供线程之间的一种通知机制,当某一条件满足时,线程A可以通知阻塞在条件变量上的线程B,B所期望的条件已经满足,可以解除在条件变量上的阻塞操作,继续做其他事情。
    1. 初始化条件变量。
    2. 等待条件成立。B线程释放锁,同时阻塞等待条件变量为真才行。
    3. 激活条件变量。A线程激活B线程所期望的条件。
    4. 清除条件变量。
  • 信号量:提供对临界资源的安全分配。如果存在多份临界资源,在多个线程争抢临界资源的情况下,向线程提供安全分配临界资源的方法。如果临界资源的数量为1,将退化为锁。
    1. 信号量初始化。
    2. 等待信号量。给信号量减1,然后等待直到信号量的值大于0。
    3. 释放信号量。信号量值加1。并通知其他等待线程。
    4. 销毁信号量。我们用完信号量后都它进行清理。归还占有的一切资源。
  • 令牌:一种高级的线程同步的方法。它既提供锁的安全访问临界资源的功能,又利用了条件变量使得线程争夺临界资源时是有序的。

    生产者消费者问题
    问题描述:
    一组生产者进程和一组消费者进程共享一个初始为空、大小为n的缓冲区,只有缓冲区没满时,生产者才能把消息放入到缓冲区,否则必须等待;只有缓冲区不空时,消费者才能从中取出消息,否则必须等待。由于缓冲区是临界资源,它只允许一个生产者放入消息,或者一个消费者从中取出消息。

semaphore mutex=1; //临界区互斥信号量
semaphore empty=n;  //空闲缓冲区
semaphore full=0;  //缓冲区初始化为空
producer () { //生产者进程
    while(1){
        produce an item in nextp;  //生产数据
        P(empty);  //获取空缓冲区单元     先对empty信号量操作,再对mutex信号量进行操作!
        P(mutex);  //进入临界区.
        add nextp to buffer;  //将数据放入缓冲区
        V(mutex);  //离开临界区,释放互斥信号量
        V(full);  //满缓冲区数加1
    }
}
consumer () {  //消费者进程
    while(1){
        P(full);  //获取满缓冲区单元
        P(mutex);  // 进入临界区
        remove an item from buffer;  //从缓冲区中取出数据
        V (mutex);  //离开临界区,释放互斥信号量
        V (empty) ;  //空缓冲区数加1
        consume the item;  //消费数据
    }
}

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

  • 在用户空间中实现线程
    (1)特点:内核对线程包一无所知。从内核角度考虑,就是按正常的方式管理,即单线程进程(存在运行时系统)
    (2)优点:
    用户级线程包可以在不支持线程的操作系统上实现
    保存线程状态的过程和调用程序都只是本地过程,故启动它们比进程内核调用效率更高
    不需要陷阱,不需要上下文切换,也不需要对内存高速缓存进行刷新,使得线程调用非常快捷
    (3)缺点:
    线程发生I/O或页面故障引起的阻塞时,如果调用阻塞系统调用则内核由于不知道有多线程的存在,而会阻塞整个进程从而阻塞所有线程
    一个单独的进程内部,没有时钟中断,所以不可能用轮转调度的方式调度线程
  • 在内核中实现线程
    (1)特点:
    当某个线程希望创建一个新线程或撤销一个已有线程时,它进行一个系统调用
    (2)优点:
    所有能够阻塞线程的调用都以系统调用的形式实现,代价可观
    当一个线程阻塞时,内核根据选择可以运行另一个进程的线程,而用户空间实现的线程中,运行时系统始终运行自己进程中的线程
    说明:由于内核创建线程代价大,有些系统采取“环保”的处理方式:线程被撤销时,标记为不可用,但是内部数据结构没有受到影响;稍后,在必须启用一个新线程时,重新启动某个旧线程,从而节省了开销。

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

一、用户态 内核态的概念
内核态与用户态是操作系统的两种运行级别,intel cpu提供Ring0-Ring3三种级别的运行模式。Ring0级别最高,Ring3最低。其中特权级0(Ring0)是留给操作系统代码,设备驱动程序代码使用的,它们工作于系统核心态;而特权极3(Ring3)则给普通的用户程序使用,它们工作在用户态。
用户态 内核态图
二、为什么要划分用户态与内核态
由于需要限制不同的程序之间的访问能力, 防止他们获取别的程序的内存数据, 或者获取外围设备的数据, 并发送到网络, CPU划分出两个权限等级 – 用户态 和内核态。

用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取
内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序

三、用户态与核心态的区别
处于用户态执行中的进程,其所能访问的内存空间和对象受到限制,其所处于占有的处理机是可被抢占的;
处于核心态执行中的进程,其能访问所有的内存空间和对象,且所占有的处理机是不允许被抢占的。

四、用户态向核心态的转换方式

  • 系统调用:用户态进程通过系统调用申请使用操作系统提供的服务程序完成工作。
  • 异常:当CPU在执行运行在用户态下的程序时,发生了某些事先不可知的异常,这时会触发由当前运行进程切换到处理此异常的内核相关的程序中,也就是转到了内核态,比如缺页异常。
  • 外围设备的中断:当外围设备完成用户请求的操作后,会向CPU发出相应的中断信号,这时CPU会暂停执行下一条即将要执行的指令转而去执行与中断信号对应的处理程序,如果先前执行的指令是用户态下的程序,那么这个转换的过程自然也就发生了由用户态到内核态的切换。比如硬盘读写操作的完成,系统会切换到硬盘读写的中断处理程序中执行后续操作等。

7. 用户栈和内核栈的区别

一、用户栈和内核栈的概念
内核在创建进程的时候,在创建task_struct的同时,会为进程创建相应的堆栈。每个进程会有两个栈,一个用户栈,存在于用户空间;一个内核栈,存在于内核空间。
当进程在用户空间运行时,cpu堆栈指针寄存器里面的内容是用户堆栈地址,使用用户栈;
当进程在内核空间运行时,cpu堆栈指针寄存器里面的内容是内核栈空间地址,使用内核栈。

二、用户栈和内核栈的区别

  • 概念上的区别:
    内核栈是系统运行在内核态的时候使用的栈,用户栈是系统运行在用户态时候使用的栈。
    当进程由于中断进入内核态时,系统会把一些用户态的数据信息保存到内核栈中,当返回到用户态时,取出内核栈中得信息恢复出来,返回到程序原来执行的地方。
  • 所述的区域不一样:
    内核栈是属于操作系统空间的一块固定区域,可以用于保存中断现场、保存操作系统子程序间相互调用的参数、返回值等。
    用户栈是属于用户进程空间的一块区域,用户保存用户进程子程序间的相互调用的参数、返回值等。

三、设置用户栈和内核栈的原因

  • 共享原因:
    内核的代码和数据是为所有的进程共享的,如果不为每一个进程设置对应的内核栈,那么就不能实现不同的进程执行不同的代码。
  • 安全原因:
    如果只有一个栈,那么用户就可以修改栈内容来突破内核安全保护。

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

一、池的概念
由于服务器的硬件资源“充裕”,那么提高服务器性能的一个很直接的方法就是以空间换时间,即“浪费”服务器的硬件资源,以换取其运行效率。这就是池的概念。池是一组资源的集合,这组资源在服务器启动之初就完全被创建并初始化,这称为静态资源分配。当服务器进入正是运行阶段,即开始处理客户请求的时候,如果它需要相关的资源,就可以直接从池中获取,无需动态分配。很显然,直接从池中取得所需资源比动态分配资源的速度要快得多,因为分配系统资源的系统调用都是很耗时的。当服务器处理完一个客户连接后,可以把相关的资源放回池中,无需执行系统调用来释放资源。从最终效果来看,池相当于服务器管理系统资源的应用设施,它避免了服务器对内核的频繁访问。
池可以分为多种,常见的有内存池、进程池、线程池和连接池。

二、内存池
c++内存分配优先使用内存池,而不是new,delete。
new和delete首先会转调用到malloc和free,这个大家应该很熟识了。很多人认为malloc是一个很简单的操作,其实巨复杂,它会执行一个系统调用(当然不是每一次,windows上是按页算),该系统调用会锁住内存硬件,然后通过链表的方式查找空闲内存,如果找到大小合适的,就把用户的进程地址映射到内存硬件地址中,然后释放锁,返回给进程。如果在多线程环境下,进程内的分配也会上锁,跟上面类似,不过不是以页,而是以分配的内存为单位。

内存池就是预先分配好,放到进程空间的内存块,用户申请与释放内存其实都是在进程内进行,SGI-STL的alloc遇到小对象时就是基于内存池的。只有当内存池空间不够时,才会再从系统找一块很大的内存。 所以使用内存池提升了内存分配与回收的效率。

三、进程池与线程池
进程池和线程池相似,所以这里我们以进程池为例进行介绍。如没有特殊声明,下面对进程池的讨论完全是用于线程池。
进程池是由服务器预先创建的一组子进程,这些子进程的数目在3~10个之间(当然这只是典型情况)。线程池中的线程数量应该和CPU数量差不多。进程池中的所有子进程都运行着相同的代码,并具有相同的属性,比如优先级、PGID等。当有新的任务来到时,主进程将通过某种方式选择进程池中的某一个子进程来为之服务(如使用随机算法或轮转法来挑选一个子进程)。当选择好子进程后,主进程还需要使用某种通知机制来告诉目标子进程有新任务需要处理,并传递必要的数据。最简单的方式是,在父进程和子进程之间预先建立好一条管道,然后通过管道来实现所有的进程间通信。在父线程和子线程之间传递数据就要简单得多,因为我们可以把这些数据定义为全局,那么它们本身就是被所有线程共享的。
综上所述,进程池的一般模型如下所示:
进程池模型

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

死锁指的是多个进程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都将无法向前推进。
导致死锁的原因:

  • 系统资源的竞争:只有对不可剥夺资源的竞争才会产生死锁。
  • 系统资源的匮乏
  • 进程推进顺序不当

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

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

11. 处理死锁的四种方式

  • 预防死锁:通过设置某些限制条件,去破坏产生死锁的四个必要条件中的一个或者几个,来预防发生死锁。
  • 避免死锁:在资源的动态分配过程中,用某种方法去防止系统进入不安全状态,从而避免发生死锁(最代表性,银行家算法)。
  • 检测死锁:允许存在死锁。通过系统所设置的检测机构,及时地检测出死锁的发生,并精确地确定与死锁有关的进程和资源,然后采取适当措施,从系统中将已发生的死锁清除
  • 解除死锁:当检测到系统中已发生死锁时,须将进程从死锁状态中解脱出来。

12. 预防死锁的方法、避免死锁的方法

一、预防死锁
死锁的预防是通过破坏产生条件来阻止死锁的产生,但这种方法破坏了系统的并行性和并发性。
死锁产生的前三个条件是死锁产生的必要条件,也就是说要产生死锁必须具备的条件,而不是存在这3个条件就一定产生死锁,那么只要在逻辑上回避了第四个条件就可以避免死锁。

二、避免死锁
避免死锁采用的是允许前三个条件存在,但通过合理的资源分配算法来确保永远不会形成环形等待的封闭进程链,从而避免死锁。该方法支持多个进程的并行执行,为了避免死锁,系统动态的确定是否分配一个资源给请求的进程。
常用的避免死锁的方法:

  • 有序资源分配法:
    这种算法资源按某种规则系统中的所有资源统一编号(例如打印机为1、磁带机为2、磁盘为3、等等),申请时必须以上升的次序。
    系统要求申请进程:
    (1)对它所必须使用的而且属于同一类的所有资源,必须一次申请完;
    (2)在申请不同类资源时,必须按各类设备的编号依次申请。
    例如:
    进程PA,使用资源的顺序是R1,R2; 进程PB,使用资源的顺序是R2,R1;
    若采用动态分配有可能形成环路条件,造成死锁。
    采用有序资源分配法:R1的编号为1,R2的编号为2;
    PA:申请次序应是:R1,R2 ; PB:申请次序应是:R1,R2
    这样就破坏了环路条件,避免了死锁的发生。

  • 银行家算法
    基本思想:分配资源之前,判断系统是否是安全的;若是,才分配。每分配一次资源就测试一次是否安全。
    我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。
    为保证资金的安全,银行家规定:
    (1)当一个顾客对资金的最大需求量不超过银行家现有的资金时就可接纳该顾客(试探性分配)。
    (2)顾客可以分期贷款,但贷款的总数不能超过最大需求量(可能一次并不能满足所需要的全部资源)。
    (3)当银行家现有的资金不能满足顾客尚需的贷款数额时,对顾客的贷款可推迟支付,但总能使顾客在有限的时间里得到贷款(不存在死锁)。
    (4)当顾客得到所需的全部资金后,一定能在有限的时间里归还所有的资金(运行后释放)。
    本算法在理论上是出色的,能非常有效地避免死锁,但从某种意义上说,它缺乏实用价值,因为很少有进程能够在运行前就知道其所需资源的最大值,且进程数也不是固定的,往往在不断地变化(如新用户登录或退出),况且原来可用的资源也可能突然间变成不可用(如打印机、磁带机可能被损坏)。


13. 进程调度算法

  • 先来先服务(FCFS , First Come First Served)
    特点:适合长作业,不利于段作业;适合CPU繁忙型作业,不利于I/O繁忙型作业。
  • 短作业优先(SJF, Shortest Job First)
    特点:提高了系统吞吐量;对长作业不利,有可能长时间得不到执行。
  • 优先级调度(HPF , Highest Priority First)
    特点:进程调度每次将处理机分配给具有最高优先级的就绪进程。最高优先级算法可与不同的CPU方式结合形成“可抢占式”最高优先级算法和“不可抢占式”最高优先级算法。常用于批处理系统。
  • 高响应比优先(HRN,Highest Response_ratio Next)
    特点:HRN是对FCFS方式和SJF方式的一种综合平衡。
    响应比R=(W + T)/ T . 其中W为等待时间,T为需要执行时间。
  • 时间片轮转算法(RR,Round Robin)
    特点:时间片轮转调度是一种最古老,最简单,最公平且使用最广的算法。将CPU的处理时间划分成一个个的时间片,就绪队列中的进程轮流运行一个时间片。当时间片结束时,就强迫进程让出CPU,该进程进入就绪队列,等待下一次调度,同时,进程调度又去选择就绪队列中的一个进程,分配给它一个时间片,以投入运行。
  • 多级队列轮转算法:几种调度算法的结合形式多级队列方式。

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

内存管理方式:块式、页式、段式、段页式
物理内存:即实际内存,实存储器。
虚拟内存:用硬盘空间做内存来弥补计算机RAM空间的缺乏。
虚拟内存好处:内存中可以保留多个进程,进程可以比内存的全部空间还大

  • 固定分区
    说明:在系统生成阶段,内存被划分成许多静态分区。进程可以被装入到大于或等于自身大小的分区。
    优势:实现简单,只需要极少的操作系统开销。
    缺点:由于有内部碎片,对内存的使用不充分;活动进程的最大数目是固定的。
  • 动态分区
    说明:分区是动态创建的,因而使得每个进程可以被装入与自身大小正好相等的分区中。
    优势:没有内部碎片;可以更充分的使用内存。
    缺点:由于需要压缩外部碎片,处理器利用率低。
  • 虚拟内存分页
    说明:内存被划分为许多大小相等的页框;每个进程被划分成许多大小与页框相等的页;不需要装入一个进程的所有页,每次只需将进程运行需要的页装入到内存中不一定连续的页框中。非驻留页在以后需要时自动调入内存。
    优势:没有外部碎片;支持更高道数的多道程序设计;巨大的虚拟地址空间。
    缺点:复杂的内存管理开销。
  • 虚拟内存分段
    说明:每个进程被划分为许多段;不需要装入一个进程的所有页,每次只需将进程运行需要的段装入到内存中不一定连续的某些动态分区中;非驻留段在以后需要时自动调入内存。
    优势:没有内部碎片;支持更高道数的多道程序设计;巨大的虚拟地址空间;支持保护与共享
    缺点:复杂的内存管理开销
  • 段页式
    分段和分页都有它们的长处。分页对程序员是透明的,它消除了外部碎片,因而可以更有效地使用内存,并且移入或移出内存的块是固定的,大小相等的。分段对程序员是可见的,它具有处理不断增长的数据结构的能力以及支持共享和保护的能力。
    在段页式的系统中,用户的地址空间被程序员划分成许多段。每个段一次划分成许多固定大小的页,页的长度等于内存中页框的大小。从程序员的角度看,逻辑地址仍然由段号和段偏移量组成,从系统的角度看,段偏移量可视为指定段中的一个页号和页偏移。

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

连续分配方式,是指为一个用户程序分配一个连续的内存空间。它主要包括单一连续分配、固定分区分配和动态分区分配。

  • 单一连续分配:内存在此方式下分为系统区和用户区,系统区仅提供给操作系统使用,通常在低地址部分;用户区是为用户提供的、除系统区之外的内存空间。这种方式无需进行内存保护。
    优点:简单、无外部碎片,可以釆用覆盖技术,不需要额外的技术支持。
    缺点:只能用于单用户、单任务的操作系统中,有内部碎片,存储器的利用率极低。
  • 固定分区分配:最简单的一种多道程序存储管理方式,它将用户内存空间划分为若干个固定大小的区域,每个分区只装入一道作业。当有空闲分区时,便可以再从外存的后备作业队列中,选择适当大小的作业装入该分区,如此循环。
  • 动态分区分配:一种动态划分内存的分区方法。这种分区方法不预先将内存划分,而是在进程装入内存时,根据进程的大小动态地建立分区,并使分区的大小正好适合进程的需要。因此系统中分区的大小和数目是可变的。

16. 动态链接及静态链接

一、分别编译与链接(Linking)

大多数高级语言都支持分别编译,程序员可以显式地把程序划分为独立的模块或文件,然后每个独立部分分别编译。在编译之后,由链接器把这些独立的片段(称为编译单元)“粘接到一起”。好处是降低了各部分模块的耦合度。
在C/C++中,这些独立的编译单元包括obj文件(一般的源程序编译而成)、lib文件(静态链接的函数库)、dll文件(动态链接的函数库)等。

静态链接方式:在程序执行之前完成所有的组装工作,生成一个可执行的目标文件(EXE文件)。
动态链接方式:在程序已经为了执行被装入内存之后完成链接工作,并且在内存中一般只保留该编译单元的一份拷贝。

二、静态链接库(LIB)与动态链接库(DLL)

先来阐述一下DLL(Dynamic Linkable Library)的概念,你可以简单的把DLL看成一种仓库,它提供给你一些可以直接拿来用的变量、函数或类。

静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib中的指令都被直接包含在最终生成的EXE文件中了。但是若使用DLL,该DLL不必被包含在最终的EXE文件中,EXE文件执行时可以“动态”地引用和卸载这个与EXE独立的DLL文件。
静态链接库的优点:
(1)代码装载速度快;
(2)只需保证在开发者的计算机中有正确的.LIB文件,在以二进制形式发布程序时不需考虑在用户的计算机上.LIB文件是否存在及版本问题,可避免DLL地狱等问题。
动态链接库的优点:
(1)更加节省内存;
(2)DLL文件与EXE文件独立,只要输出接口不变,更换DLL文件不会对EXE文件造成任何影响,因而极大地提高了可维护性和可扩展性。
静态和动态链接

三、认识动态链接库

动态链接是相对于静态链接而言的。所谓静态链接是指把要调用的函数或者过程链接到可执行文件中,成为可执行文件的一部分。换句话说,函数和过程的代码就在程序的exe文件中,该文件包含了运行时所需的全部代码。当多个程序都调用相同函数时,内存中就会存在这个函数的多个拷贝,这样就浪费了宝贵的内存资源。而动态链接所调用的函数代码并没有被拷贝到应用程序的可执行文件中去,而是仅仅在其中加入了所调用函数的描述信息(往往是一些重定位信息)。仅当应用程序被装入内存开始运行时,在Windows的管理下,才在应用程序与相应的DLL之间建立链接关系。当要执行所调用DLL中的函数时,根据链接产生的重定位信息,Windows才转去执行DLL中相应的函数代码。一般情况下,如果一个应用程序使用了动态链接库,Win32系统保证内存中只有DLL的一份复制品

动态链接库的两种链接方法:

(1) 装载时动态链接(Load-time Dynamic Linking):这种用法的前提是在编译之前已经明确知道要调用DLL中的哪几个函数,编译时在目标文件中只保留必要的链接信息,而不含DLL函数的代码;当程序执行时,调用函数的时候利用链接信息加载DLL函数代码并在内存中将其链接入调用程序的执行空间中(全部函数加载进内存),其主要目的是便于代码共享。(动态加载程序,处在加载阶段,主要为了共享代码,共享代码内存)

(2) 运行时动态链接(Run-time Dynamic Linking):这种方式是指在编译之前并不知道将会调用哪些DLL函数,完全是在运行过程中根据需要决定应调用哪个函数,将其加载到内存中(只加载调用的函数进内存),并标识内存地址,其他程序也可以使用该程序,并用LoadLibrary和GetProcAddress动态获得DLL函数的入口地址。(dll在内存中只存在一份,处在运行阶段)

上述的区别主要在于阶段不同,编译器是否知道进程要调用的dll函数。动态加载在编译时知道所调用的函数,而在运行态时则必须不知道。


17. 基本分页、请求分页存储管理方式

基本分页的特征:
(1)一次性:将作业全部装入内存后方能运行,浪费空间。
(2)驻留性:作业装入内存后,便一直驻留在内存中,直至作业运行结束。

请求分页原理:
(1)在进程开始运行之前,仅装入当前要执行的部分页面即可运行;
(2)在执行过程中,可使用请求调入中断动态装入要访问但又不在内存的页面;
(3)当内存空间已满,而又需要装入新的页面时,者根据置换功能适当调出某个页面,以便腾出空间而装入新的页面。
(4)为实现请求分页,需要一定的硬件支持,包括:页表机制、缺页中断机构、地址变换机构。


18. 基本分段、请求分段储存管理方式

基本分段的特征:一次性、驻留性;

按照用户进程中的自然段划分逻辑空间,段内要求连续,段间不要求连续,整个作业的地址空间是二维的。逻辑地址由段号S与段内偏移量W两部分组成。


19. 分段分页方式的比较各自优缺点

分页和分段的主要区别
段是信息的逻辑单位,用户可见,长度可变
页是信息的物理单位,用户透明,长度固定
段式:若干独立的逻辑空间构成进程的非连续逻辑空间,二维地址空间
页式:一维地址空间
段式:物理空间不连续,但段内连续
页式:物理空间不连续


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

1.最佳置换算法(OPT)
最佳(Optimal, OPT)置换算法所选择的被淘汰页面将是以后永不使用的,或者是在最长时间内不再被访问的页面,这样可以保证获得最低的缺页率。但由于人们目前无法预知进程在内存下的若千页面中哪个是未来最长时间内不再被访问的,因而该算法无法实现。
2.先进先出(FIFO)页面置换算法
优先淘汰最早进入内存的页面,亦即在内存中驻留时间最久的页面。该算法实现简单,只需把调入内存的页面根据先后次序链接成队列,设置一个指针总指向最早的页面。但该算法与进程实际运行时的规律不适应,因为在进程中,有的页面经常被访问。
3.最近最久未使用(LRU)置换算法
选择最近最长时间未访问过的页面予以淘汰,它认为过去一段时间内未访问过的页面,在最近的将来可能也不会被访问。该算法为每个页面设置一个访问字段,来记录页面自上次被访问以来所经历的时间,淘汰页面时选择现有页面中值最大的予以淘汰。
4.时钟(CLOCK)置换算法

LRU算法的性能接近于OPT,但是实现起来比较困难,且开销大;FIFO算法实现简单,但性能差。所以操作系统的设计者尝试了很多算法,试图用比较小的开销接近LRU的性能,这类算法都是CLOCK算法的变体。
简单的CLOCK算法是给每一帧关联一个附加位,称为使用位。当某一页首次装入主存时,该帧的使用位设置为1;当该页随后再被访问到时,它的使用位也被置为1。对于页替换算法,用于替换的候选帧集合看做一个循环缓冲区,并且有一个指针与之相关联。当某一页被替换时,该指针被设置成指向缓冲区中的下一帧。当需要替换一页时,操作系统扫描缓冲区,以查找使用位被置为0的一帧。每当遇到一个使用位为1的帧时,操作系统就将该位重新置为0;如果在这个过程开始时,缓冲区中所有帧的使用位均为0,则选择遇到的第一个帧替换;如果所有帧的使用位均为1,则指针在缓冲区中完整地循环一周,把所有使用位都置为0,并且停留在最初的位置上,替换该帧中的页。由于该算法循环地检查各页面的情况,故称为CLOCK算法,又称为最近未用(Not Recently Used, NRU)算法。
CLOCK算法的性能比较接近LRU,而通过增加使用的位数目,可以使得CLOCK算法更加高效。在使用位的基础上再增加一个修改位,则得到改进型的CLOCK置换算法。这样,每一帧都处于以下四种情况之一:
最近未被访问,也未被修改(u=0, m=0)。
最近被访问,但未被修改(u=1, m=0)。
最近未被访问,但被修改(u=0, m=1)。
最近被访问,被修改(u=1, m=1)。
算法执行如下操作步骤:
1)从指针的当前位置开始,扫描帧缓冲区。在这次扫描过程中,对使用位不做任何修改。选择遇到的第一个帧(u=0, m=0)用于替换。
2)如果第1)步失败,则重新扫描,查找(u=0, m=1)的帧。选择遇到的第一个这样的帧用于替换。在这个扫描过程中,对每个跳过的帧,把它的使用位设置成0。
3)如果第2)步失败,指针将回到它的最初位置,并且集合中所有帧的使用位均为0。重复第1步,并且如果有必要,重复第2步。这样将可以找到供替换的帧。
改进型的CLOCK算法优于简单CLOCK算法之处在于替换时首选没有变化的页。由于修改过的页在被替换之前必须写回,因而这样做会节省时间。


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

基于局部性原理,在程序装入时,可以将程序的一部分装入内存,而将其余部分留在外存,就可以启动程序执行。在程序执行过程中,当所访问的信息不在内存时,由操作系统将所需要的部分调入内存,然后继续执行程序。另一方面,操作系统将内存中暂时不使用的内容换出到外存上,从而腾出空间存放将要调入内存的信息。这样,系统好像为用户提供了一个比实际内存大得多的存储器,称为虚拟存储器。

之所以将其称为虚拟存储器,是因为这种存储器实际上并不存在,只是由于系统提供了部分装入、请求调入和置换功能后(对用户完全透明),给用户的感觉是好像存在一个比实际物理内存大得多的存储器。虚拟存储器的大小由计算机的地址结构决定,并非是内存和外存的简单相加。虚拟存储器有以下三个主要特征:
1. 多次性,是指无需在作业运行时一次性地全部装入内存,而是允许被分成多次调入内存运行。
2. 对换性,是指无需在作业运行时一直常驻内存,而是允许在作业的运行过程中,进行换进和换出。
3. 虚拟性,是指从逻辑上扩充内存的容量,使用户所看到的内存容量,远大于实际的内存容量。
实现方式:
1. 请求分页存储管理。
2. 请求分段存储管理。
3. 请求段页式存储管理。


22. 操作系统的四个特性

操作系统的4个特征是并发性、共享性、虚拟性和不确定性。
并发性(concurrency):指在计算机系统中存在着许多并发执行的活动。对计算机系统而言,并发是指宏观上看系统内有多道程序同时运行,微观上看是串行运行。因为在大多数计算机系统中一般只有一个CPU,在任意时刻只能有一道程序占用CPU。

共享性(sharing):系统中各个并发活动要共享计算机系统中的各种软、硬件资源,因此操作系统必须解决在多道程序间合理地分配和使用资源问题。

虚拟性(virtual):虚拟是操作系统中的重要特征,所谓虚拟是指把物理上的一台设备变成逻辑上的多台设备。例如,在操作系统中采用了spooling技术,可以利用快速、大容量可共享的磁盘作为中介,模拟多个非共享的低速的输入输出设备,这样的设备称为虚拟设备。

异步性(Asynchronism):多道程序环境下程序的执行,是以异步方式进行的;是操作系统的一个重要特征。换言之,每个程序在何时执行,多个程序间的执行顺序以及完成每道程序所需的时间都是不确定的,因而也是不可预知的。

操作系统的五大管理功能是进程管理、文件管理、存储管理、设备管理和作业管理。


23. DMA

Direct Memory Access(存储器直接访问):这是指一种高速的数据传输操作,允许在外部设备和存储器之间直接读写数据,既不通过CPU,也不需要CPU干预。整个数据传输操作在一个称为”DMA控制器”的控制下进行的。CPU除了在数据传输开始和结束时做一点处理外,在传输过程中CPU可以进行其他的工作。这样,在大部分时间里,CPU和输入输出都处于并行操作。因此,使整个计算机系统的效率大大提高。

目的:让设备可以绕过CPU,直接读写系统内存
原理:在一段时间内,由DMA控制器取代CPU,获得总线控制权,从而实现内存与外设或者内存不同区域间的大量数据快速传递
特点:允许不同速度的硬件装置来沟通,不需要依于 CPU 的大量中断负载

外设向DMA控制器请求→DMA控制器向CPU请求→DMA控制器获得总线→传输数据→字节计数器为0时DMA结束→返还总线给CPU


24. Spooling

为了缓和CPU的高速性与I/O设备低速性之间的矛盾而引入了脱机输入/输出技术。该 技术是利用专门的外围控制机,将低速I/O设备上的数据传送到高速磁盘上;或者相反。 Spooling的意思是外部设备同时联机操作,又称为假脱机输入/输出操作,是操作系统中釆用的一项将独占设备改造成共享设备的技术。

目的:为了缓和CPU的高速性与I/O设备低速性之间的矛盾
原理:利用专门的外围控制机,将低速I/O设备上的数据传送到高速磁盘上;或者相反。
特点:提高了 I/O的速度;将独占设备改造为共享设备;实现了虚拟设备功能。

输入设备→输入缓冲区→输入井→内存→输出井→输出缓冲区→输出设备


25. 外存分配的几种方式,及各种优劣

外存分配方式主要有这几种:连续分配,链式分配,索引分配。
一. 连续分配
原理:创建文件时,分配一组连续的块;FAT(文档分配表)中每个文件只要一项,说明起始块和文件长度。对于顺序文件有利。
优点:1.简便。适用于一次性写入操作。2.支持顺序存取和随机存取,顺序存取速度快。3.所需的磁盘寻道次数和寻道时间最少。(因为空间的连续性,当访问下一个磁盘块时,一般无需移动磁头,当需要移动磁头时,只需要移动一个磁道。)
缺点:1.文件不能动态增长。(可能文件末尾处的空块已经分配给了别的文件。)2.不利于文件的插入和删除。3.外部碎片问题。(反复增删文件后,很难找到空间大小足够的连续块,需要进行紧缩。)4.在创建文件时需生命文件大小。
如图:

二. 链式分配
原理:一个文件的信息存放在若干个不连续的物理块中,各块之间通过指针连接,前一个物理块指向下一个物理块。fat中每个文件同样只需要一项,包括文件名、起始块号和最后块号。任何一个自由块都可以加入到链中。
优点:1.提高磁盘的空间利用率,不存在外部碎片问题。2.有利于文件的插入和删除。3.有利于文件的动态扩充。
缺点:1.存取速度慢,一般只适用于信息的顺序存取,不适于随机存取。2.查找某一块必须从头到尾沿着指针进行。3.可靠性问题,如指针出错。4.更多的寻道次数和寻道时间。5.链接指针占一定的空间,将多个块组成簇,按簇进行分配而不是按块进行分配。(增加了磁盘碎片)
如图:
使用FAT文件分配表法,链接分配的变种,如MS-DOS 和 OS/2.

三. 索引分配
原理:每个文件在FAT中有一个一级索引,索引包含分配给文件的每个分区的入口。文件的索引保存在单独的一个块中,FAT中该文件的入口指向这一块。
优点:1.保持了链接结构的优点,又解决了其缺点:按快分配可以消除外部碎片。按大小可改变的分区分配可以提高局部性。索引分配支持顺序访问文件和直接访问文件,是普遍采用的一种方式。2.满足了文件动态增长,插入删除的要求。(只要有空闲块)3.能充分利用外存空间。
缺点:1.较多的寻道次数和寻道空间。2.索引表本身带来了系统开销,如:内外存空间、存取时间。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

操作系统知识点整理 的相关文章

  • Find Pivot Index(LeetCode 724)

    本想用贪心结果WA xff0c 看来只能老老实实的用枚举了 xff0c 简单粗暴实用 枚举中心轴 xff0c 从0开始 xff0c 定义两个变量left 和 right分别代表轴左边的数据之和以及轴右边的数据之和 xff0c 判断left是
  • B - fLIP

    题目链接 xff1a http code festival 2017 quala contest atcoder jp tasks code festival 2017 quala b 解题思路 xff1a 一个棋盘有N行 xff0c M列
  • 无根树转有根数

    include lt stdio h gt include lt vector gt include lt queue gt using namespace std const int maxn 61 1000 43 10 vector l
  • 【VC ++ 2010】 C语言 计算机二级编译器 Visual C ++ 2010 Express(中文学习版)的安装与使用

    文章目录 1 安装包地址2 安装2 1 安装VC 43 43 20102 2 打开VC 43 43 20102 3 注册 3 使用3 1 新建项目3 2 打开项目3 3 编写C文件并运行 1 安装包地址 链接 xff1a https pan
  • 怎样解题表

    怎样解题表是由美国数学家G 波利特提出的 具体的介绍见 xff1a https baike baidu com item E6 80 8E E6 A0 B7 E8 A7 A3 E9 A2 98 551528 fr 61 aladdin 怎样
  • C++中的::运算符

    原文出处 xff1a http blog csdn net libing zeng article details 54412935 一两行以上的成员函数最好被定义在类体之外 这要求一个特殊的声明语化来标识一 个函数是一个类的成员 xff1
  • C++创建类并应用

    新建一个Point h文件 在该文件中定义Point类 xff0c 代码如下 ifndef POINT H define POINT H class Point public Point void setPoint int x int y
  • UVA808(对蜂窝建立坐标系)

    这个题我是通过建立坐标系加找规律做出来的 xff0c 个人感觉难点是建立坐标系 xff0c 所以我将着重讲一下坐标系是怎么建立的 建立坐标系 xff1a 如果你有兴趣的话 xff0c 你可以将他给的图沿横线延长 xff0c 这样一个正六边形
  • Cats and Fish2017北京赛区网络同步赛

    题目链接 xff1a http hihocoder com problemset problem 1631 首先根据吃鱼的速度从小到大排序 xff0c 然后从1到x按着时间轴枚举猫的行为 xff0c 如果是吃完一条判断一下他的状态是正在吃鱼
  • leetcode729. My Calendar I

    设一个字典记录所有被预定的页面 xff0c 然后就是判断区间相交了 当发生以下两种情况之一时认为区间相交 1 起点小于左端点且终点大于左端点 2 起点大于等于左端点且起点小于右端点 代码如下 span class hljs class sp
  • 搭建java web开发环境(eclipse)

    引论 工欲善其事 xff0c 必先利其器 xff1b 想要进行web开发就必须有一款顺手的武器 xff0c eclipse作为一款知名的IDE自然是一个不错的选择 准备 eclipse依赖于JDK xff0c 所以我们在安装eclipse之
  • 安装codeblocks(win10)

    下载 进入http www codeblocks org downloads 26 xff0c 选择与你电脑对应的codeblocks版本 xff0c 这里以win10为例 xff0c 下载windows平台的codeblocks 注意要选
  • B - Palindrome-phobia(CODE FESTIVAL 2017 Final)

    题目链接 https cf17 final open contest atcoder jp tasks cf17 final b 解题思路 通过找规律发现出现的次数最多的字符与其他两个字符数量的差不能大于1 AC代码 include lt
  • poj1061青蛙的约会

    题目链接 http poj org problem id 61 1061 题目类型 扩展欧几里得算法 解题思路 设青蛙A为速度快的那只 xff0c 则有 m n t k l 61 y x 令a 61 m n b 61 l c 61 y c则
  • Android Studio中安装Kotlin插件

    http blog csdn net cto 1649900265 article details 72628878 这个链接内介绍了安装Kotlin插件的步骤 步骤 xff1a 在Android Studio中打开Settings xff
  • 骰子的游戏(牛客练习赛7)

    题目链接 https www nowcoder com acm contest 38 A 解题方法 枚举 AC代码 include lt stdio h gt const int maxn 61 10 43 5 int a maxn b m
  • C - Shopping Street(AtCoder Beginner Contest 080)

    题目链接 https beta atcoder jp contests abc080 tasks abc080 c 解题方法 因为一共只有十个时期所以我们可以枚举所有的状态 xff0c 又因为必须有1个时期开放 xff0c 所以我们从1而不
  • 经典OJ推荐

    转载自http acdream info topic tid 61 101 一 Online Judge简介 Online Judge系统 xff08 简称OJ xff09 是一个在线的判题系统 用户可以在线提交程序多种程序 xff08 如
  • 安装Tomcat(win10)

    引论 做web项目已经是一个很常见的事情了 xff0c 而我们完成后的web项目要想发布除了硬件的服务器外还需要相应的服务器软件 xff0c 而Tomcat就是一款web应用服务器 尽管因为Nginx xff08 它的性能是Apache服务

随机推荐

  • org.hibernate.InstantiationException: No default constructor for entity: cn.gov.entity.Book

    出错地方 xff1a org hibernate InstantiationException No default constructor for entity cn gov entity Book 出错原因 xff1a hibernat
  • 牛客练习赛8 D加边的无向图

    题目链接 https www nowcoder com acm contest 39 D 解题思路 利用并查集查找一共有几个独立的集合 xff0c 最后需要的最少边为集合个数减一 AC代码 include lt stdio h gt inc
  • 解决getHibernateTemplate().save ()不能将数据保存到数据库的问题

    原文出自http blog csdn net justerdu article details 50893583 分析 xff1a 数据是保存在缓存中而未提交到数据库中 解决办法 xff1a 在hibernate cfg xml里面加入 h
  • 输入ctrl s终端冻结怎么办

    原文出自http www xshellcn com zhishi sr ztd html 大家有没有发现每当输入ctrl s 就暂停该终端 让人着急万分 xff0c 我相信这是很多xshell的用户都会遇到的一个问题 xff0c 那应该怎么
  • java大数详解

    引论 在算法竞赛中我们经常遇到大数问题 xff0c 例如求一个很大的斐波那契数 住在这种情况下我们用常规解法 xff08 使用long long或long long int xff09 肯定是不行的 xff0c 而我们自己写一个大数的算法又
  • ACM数论模板及应用

    引论 数论是算法竞赛的宠儿 xff0c 几乎每个算法竞赛 xff08 不论是ACM的省赛 区域赛还是牛客网上的网络赛 xff09 都会出一道关于数论的题 这很容易理解 xff0c 因为算法与数学的关系极其密切 xff0c 也可以说算法拼到最
  • 深度神经网络的应用

    深度学习能应用在哪些领域 xff1f 深度学习的快速发展 xff0c 不仅使机器学习得到许多实际的应用 xff0c 还拓展了整个AI xff08 人工智能的 xff09 的范围 它将任务进行拆解 xff0c 使得各种类型的机器辅助变成可能
  • <操作系统>读者写者问题(写者优先)C语言实现

    问题描述 代码 span class token macro property span class token directive keyword include span span class token string lt stdio
  • 二叉树的节点个数以及高度详解(附图解)

    二叉树的节点个数以及高度 文章目录 二叉树的节点个数以及高度前言NO 1 定义链式二叉树NO 2 创建二叉树一 二叉树节点个数1 代码展示2 递归图解 二 二叉树叶子节点个数1 代码展示2 递归图解 三 二叉树第k层节点个数1 代码展示2
  • 使用Github Desktop轻松进行版本管理

    引论 现在git已经成为了主流的版本管理软件 xff0c 然而是不是有一些一看到命令行就头痛的初学者 xff08 比如我 xff09 呢 xff1f 不过好在有着各种各样的图形界面软件可以帮助我们摆脱这一烦恼 xff0c 就比如说githu
  • Leetcode 100. Same Tree

    分析 这道题算是一道关于树的简单题 xff0c 我们需要判断给出的两棵树是否相等 xff0c 分为三步 xff0c 判断当前节点是否相等 xff0c 判断左右子树是否相等 要特别注意一下为NULL的情况 我的代码 span class hl
  • Python小程序之文件清理机

    背景 作为一名Acmer我写了很多 cpp文件 xff0c 其中经过编译 链接后又生成了许多 exe和 o文件 当我用github desktop将他们同步到我的github上是 exe和 o文件很碍事 xff0c 尤其是 exe文件占用的
  • hdu1076

    题目链接 An Easy Task 解题思路 题目要求给出一个年份Y和一个整数N xff0c 输入从Y年起第N个闰年 首先我们容易知道我们需要判断一个年份是否是闰年 xff0c 我们可以把它封装成一个函数 xff0c 这样可以方便我们下次调
  • 牛客练习赛12 B迷宫解题报告

    一切尽在代码中 include lt stdio h gt include lt string h gt include lt queue gt include lt algorithm gt using namespace std con
  • 利用并查集维护两个对立集合

    在并查集的实际应用中 xff0c 我们经常遇到下列这种情况的题目 当满足 1 x xff0c y为不同集合的元素 2 x xff0c z为不同集合元素 时 xff0c y xff0c z为相同集合的元素 如何来描述这种不同集合元素的关系就是
  • HDU - 3018解题报告

    题意简述 给出n个节点 xff0c m条边 xff0c 问要想全部经过这m条边且每个边只经过一次至少需要多少条路径 分析 这个题实际上就是一笔画问题中的定理二 xff1a 如果连通无向图 G 有 2k 个奇顶点 xff0c 那么它可以用 k
  • 手把手教你申请企鹅号

    引论 随着互联网时代的兴起 xff0c 自媒体越来越引人注目 笔者周围已经有了不少人开始做自媒体而且还做的顺风顺水 笔者也有些按捺不住 xff0c 寻思着要做自媒体的生意 xff0c 可是转念一想 xff0c 独赚钱不如众赚钱 xff0c
  • UVA818解题报告

    span class hljs comment UVA 818 理解了题意和水题差不多 条件 xff1a 一些可能相同的无向边 要求 xff1a 构建一个满足如下三个要求的图 一 不能有环 二 连成一条直线 三 所有节点要连在一起 操作 x
  • PAT1003 Emergency (25)

    引论 本以为这是一道水题却因为考虑不周WA了半天 xff0c 参考了博客https blog csdn net tiantangrenjian article details 19434417 感觉这题还是蛮不错的 题目链接 https p
  • 操作系统知识点整理

    1 进程的有哪几种状态 xff0c 状态转换图 xff0c 及导致转换的事件 进程的状态 xff1a 运行 阻塞 就绪三种状态 运行和就绪之间的转换由调度程序引导 xff1b 当进程等待一个外部事件发生时 xff0c 则由执行 阻塞 xff