操作系统 200312

1. 什么是僵尸进程?什么是孤儿进程?有什么危害?

僵尸进程:

  • 一个进程使用 fork 创建子进程,如果子进程退出,而父进程并没有调用 wait 或者 waitpid
    获取子进程的状态信息,那么子进程的进程描述符等一系列信息还会保存在系统中。这种进程称之为僵尸进程。
  • “僵尸” 进程是一个早已死亡的进程,但在进程表(processs
    table)中仍占了一个位置(slot)。由于进程表的容量是有限的,所以,defunct
    进程不仅占用系统的内存资源,影响系统的性能,而且如果其数目太多,还会导致系统瘫痪。

处理僵尸进程:

  • 改写父进程,在子进程死后要为它收尸。具体做法是接管 SIGCHLD 信号。子进程死后,会发送 SIGCHLD
    信号给父进程,父进程收到此信号后,执行 waitpid () 函数为子进程收尸。这是基于这样的原理:就算父进程没有调用
    wait,内核也会向它发送 SIGCHLD 消息,尽管默认处理是忽略,如果想响应这个消息,可以设置一个处理函数。
  • 把父进程杀掉。父进程死后,僵尸进程成为” 孤儿进程”,过继给 1 号进程 init,init
    始终会负责清理僵尸进程.它产生的所有僵尸进程也跟着消失。

孤儿进程:

  • 父进程运行结束,但子进程还在运行 (未运行结束) 的子进程就称为孤儿进程。
  • 孤儿进程最终会被 init 进程 (进程号为 1) 所收养,因此 init 进程此时变成孤儿进程的父进程,并由 init
    进程对它们完成状态收集工作。

2. CPU的上下文切换有几种?系统中断进行了几次上下文切换?

上下文切换 (Context Switch) 是一种将 CPU 资源从一个进程分配给另一个进程的机制。操作系统需要先存储当前进程的状态 (包括内存空间的指针,当前执行完的指令等等),再读入下一个进程的状态,然后执行此进程。

CPU 的上下文切换分三种:进程上下文切换、线程上下文切换、中断上下文切换。

系统调用过程中也会发生 CPU 上下文切换。CPU 寄存器会先保存用户态的状态,然后加载内核态相关内容。系统调用结束之后,CPU 寄存器要恢复原来保存的用户态,继续运行进程。所以,一次系统调用,发生两次 CPU 上下文切换。

进程是由内核管理和调度的,进程的切换只能发生在内核态。进程上下文切换与系统调用的不同在于,进程的调用会保存用户空间的虚拟内存,全局变量等信息,但是系统调用的上下文则不会,因为其未发生进程的变化。

内核中的任务调度实际是在调度线程,进程只是给线程提供虚拟内存、全局变量等资源。线程上下文切换时,共享相同的虚拟内存和全局变量等资源不需要修改。而线程自己的私有数据,如栈和寄存器等,上下文切换时需要保存。

3. 进程的通信方式?效率最高的通信方式是什么?

  • 管道:管道是单向的、先进先出的、无结构的、固定大小的字节流,它把一个进程的标准输出和另一个进程的标准输入连接在一起。写进程在管道的尾端写入数据,读进程在管道的道端读出数据。数据读出后将从管道中移走,其它读进程都不能再读到这些数据。管道提供了简单的流控制机制。进程试图读空管道时,在有数据写入管道前,进程将一直阻塞。同样地,管道已经满时,进程再试图写管道,在其它进程从管道中移走数据之前,写进程将一直阻塞。
  • 信号量:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其它进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
  • 消息队列:是一个在系统内核中用来保存消息的队列,它在系统内核中是以消息链表的形式出现的。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
  • 共享内存:共享内存允许两个或多个进程访问同一个逻辑内存。这一段内存可以被两个或两个以上的进程映射至自身的地址空间中,一个进程写入共享内存的信息,可以被其他使用这个共享内存的进程,通过一个简单的内存读取读出,从而实现了进程间的通信。如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进程。共享内存是最快的
    IPC 方式,它是针对其它进程间通信方式运行效率低而专门设计的。它往往与其它通信机制(如信号量)配合使用,来实现进程间的同步和通信。
  • 套接字:套接字也是一种进程间通信机制,与其它通信机制不同的是,它可用于不同机器间的进程通信。

4. 进程调度算法有几种?应用最广泛的是什么?

批处理任务:

  • 先来先服务 (FCFS)
  • 短作业优先(SJF)
  • 最短剩余时间优先(SRTN)
  • 优先权调度

交互式任务:

  • 时间片轮转
  • 多级调度队列
  • 多级反馈队列

FIFO 或 First Come, First Served (FCFS) 先来先服务

  • 调度的顺序就是任务到达就绪队列的顺序。
  • 公平、简单 (FIFO 队列)、非抢占、不适合交互式。
  • 未考虑任务特性,平均等待时间可以缩短。

Shortest Job First (SJF) 最短作业优先

  • 最短的作业 (CPU 区间长度最小) 最先调度。
  • 由于作业的长短只是根据用户所提供的估计执行时间而定的,而用户又可能会有意或无意地缩短其作业的估计运行时间,致使该算法不一定能真正做到短作业优先调度。
  • SJF 可以保证最小的平均等待时间。

Shortest Remaining Job First (SRJF) 最短剩余作业优先

  • SJF 的可抢占版本,比 SJF 更有优势。
  • SJF (SRJF): 如何知道下一 CPU 区间大小?根据历史进行预测:指数平均法。

优先权调度

  • 每个任务关联一个优先权,调度优先权最高的任务。
  • 优先权太低的任务一直就绪,得不到运行,出现 “饥饿” 现象。

Round-Robin (RR) 轮转调度算法

  • 设置一个时间片,按时间片来轮转调度(“轮叫” 算法)
  • 优点:定时有响应,等待时间较短;
  • 缺点:上下文切换次数较多;

时间片太大,响应时间太长;吞吐量变小,周转时间变长;当时间片过长时,退化为 FCFS。

多级队列调度

  • 按照一定的规则建立多个进程队列
  • 不同的队列有固定的优先级(高优先级有抢占权)
  • 不同的队列可以给不同的时间片和采用不同的调度方法
  • 存在问题 1:没法区分 I/O bound 和 CPU bound;
  • 存在问题 2:也存在一定程度的 “饥饿” 现象;

多级反馈队列

  • 在多级队列的基础上,任务可以在队列之间移动,更细致的区分任务。

  • 可以根据 “享用” CPU 时间多少来移动队列,阻止 “饥饿”。

  • 最通用的调度算法,多数 OS 都使用该方法或其变形,如

    UNIX、Windows 等。

多级反馈队列算法详解:

  • 进程在进入待调度的队列等待时,首先进入优先级最高的 Q1 等待。

  • 首先调度优先级高的队列中的进程。若高优先级中队列中已没有调度的进程,则调度次优先级队列中的进程。例如:Q1,Q2,Q3 三个队列,只有在
    Q1 中没有进程等待时才去调度 Q2,同理,只有 Q1,Q2 都为空时才会去调度 Q3。

  • 对于同一个队列中的各个进程,按照时间片轮转法调度。比如 Q1 队列的时间片为 N,那么 Q1 中的作业在经历了 N
    个时间片后若还没有完成,则进入 Q2 队列等待,若 Q2 的时间片用完后作业还不能完成,一直进入下一级队列,直至完成。

  • 在低优先级的队列中的进程在运行时,又有新到达的作业,那么在运行完这个时间片后,CPU 马上分配给新到达的作业(抢占式)。

5. 进程和线程的区别?

进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。

线程是进程的一个实体,是 CPU 调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。

区别:

  • 进程有自己的独立地址空间,线程没有
  • 进程是资源分配的最小单位,线程是 CPU 调度的最小单位。
  • 进程和线程通信方式不同
    (线程之间的通信比较方便。同一进程下的线程共享数据,比如全局变量,静态变量,通过这些数据来通信不仅快捷而且方便,当然如何处理好这些访问的同步与互斥正是编写多线程程序的难点。而进程之间的通信只能通过进程通信的方式进行。)
  • 进程上下文切换开销大,线程开销小;对进程进程操作一般开销都比较大,对线程开销就小了
  • 一个进程挂掉了不会影响其他进程,而线程挂掉了会影响其他线程。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值