操作系统笔记4

进程的概念

进程调度

多道程序设计的目的是无论何时都有进程在运行,从而使CPU的利用效率最大化。

为了达到此目的,进程调度选择一个可用的进程到CPU执行

  • Job queue,作业队列:在系统中
  • Ready queue,就绪队列:在内存中,等待被执行
  • Device queue,设备队列:一组等待I/O的进程

调度队列和调度程序

进程进入系统时,会被加入到作业队列中。驻留在内存中就绪的、等待运行的会保存在就绪队列中。该队列一般通过链表的形式来实现。

  • 长程调度程序/作业调度程序:从磁盘后备队列->内存,执行频率不高,用于控制进程道数
  • 短程调度程序/CPU调度程序:执行频率高

表示进程调度的队列图

上下文切换

将CPU切换到另一个进程需要保存当前进程的状态并恢复另一个进程的状态,这一任务称为上下文切换。

当发生上下文切换时,内核会将旧进程的状态保存在其PCB中。然后装入要执行的新进程的上下文。

进程操作

进程创建

进程在其执行的过程中,能通过创建进程系统调用,create-process system call来创建多个新进程。创建进程称为父进程,新进程称为子进程。每个进程都可以创建新进程,从而形成进程树

  • 进程创建新进程时,有两种执行可能:
    1. 父进程和子进程并发执行
    2. 父进程等待,直到某个或全部子进程执行完
  • 新进程的地址空间也有两种可能:
    1. 子进程是父进程的复制品
    2. 子进程装入另一个新程序

一个进程创建的步骤:

作业调度->申请空白PCB,分配资源,填写PCB相关内容(new状态)->进入ready队列

进程终止

当进程执行完最后的语句,使用系统调用exit()请求操作系统删除自身时,进程终止。

其他情况下,进程也会终止。进程通过适当的系统调用可以终止另一个进程。

父进程终止子进程的原因:

  1. 子进程使用了超过它所分配到的一些资源
  2. 分配给子进程的任务已经不再需要
  3. 父进程退出。

进程间通信

如果一个进程不能影响其他进程或被其他进程所影响,那么该进程是独立的。反之则是协作的。

允许进程协作的理由:

  1. 提高运算速度
  2. 信息共享
  3. 模块化
  4. 方便

进程间通信有两种基本模式:1.共享内存 2.消息传递

共享内存

采用共享内存的进程间通信需要通信进程建立共享内存区域。这是一个经典的生产者-消费者问题

采用共享内存是解决生产者-消费者问题的一种。为了允许生产者和消费者进程能够并发执行,必须有一个缓冲来被生产者填充并被消费者使用。此缓冲驻留在生产者进程和消费者进程的共享内存区域内。

可以使用两种缓冲:无限缓冲,消费者不得不等待新的项,但生产者总是可以产生新的项,有限缓冲,假设缓冲大小固定,缓冲为空时,消费者必须等待。缓冲为满时,生产者必须等待

有限缓冲的共享缓冲是使用循环数组,两个逻辑指针来实现的:

  • in指针指向缓冲中的下一个空位,当(in+1)%size==out时,缓冲为满
  • out指针指向缓冲中的第一个满位,当in==out时,缓冲为空
  • 这种方法允许的缓冲最大项数为size-1

消息传递系统

两进程之间需要相互通信,他们之间必须要有通信线路。

直接通信:

需要通信的每对进程之间自动建立线路(双向),发送和接收进程必须命名对方以便通信

间接通信:邮箱

两个进程仅在其共享至少一个邮箱时可以相互通信。

同步问题

消息的传递可以是阻塞或非阻塞的,也称为同步和异步

  • 阻塞send:发送进程阻塞,直到消息被接收进程或邮箱所接收
  • 非阻塞send:发送进程发送消息并继续操作
  • 阻塞receive:接收者阻塞,直到有消息可用
  • 非阻塞receive:接收者收到一个有效消息或空消息

结果需要确定,用阻塞;结果不需要确定,用非阻塞。