操作系统期末复习(一)——进程/信号量/PV操作实例分析

目录

进程

进程相关概念

进程状态转移模型(☆)

信号量机制

记录型信号量

PV操作实例分析(☆☆)

生产者与消费者问题(课本P57 例3-1)

生产者与消费者的变形问题(课本P61 例3-5)


进程

进程相关概念

  1. 进程:正在执行的程序实例,包含代码、数据和PCB(运行时状态)。

  2. 线程:进程内部的执行单元,共享同一个进程的地址空间和其他资源。

  3. 进程控制块(PCB):系统为每个进程维护的数据结构,包含了进程的基本信息和状态。当操作系统需要对进程进行调度或管理时,就会通过访问进程控制块来获取必要的信息。

  4. 进程调度:操作系统根据一定的算法选择下一个应该执行的进程的过程。

  5. 上下文切换:在多道程序系统中,由于CPU时间片轮转或等待输入输出等原因,操作系统需要从当前进程切换到另一个进程,这个过程称为上下文切换。

  6. 进程同步:在多道程序环境下,不同进程之间可能需要相互协作完成任务,但由于资源竞争的问题,可能会导致数据不一致或死锁等问题。进程同步就是为了解决这些问题而采用的一些机制,如信号量、互斥量、条件变量等。

  7. 进程通信:不同进程之间相互传递信息的过程。有多种方式可以实现进程间通信,如管道、共享内存、消息队列等。

程状态转移模型(☆)

进程的五状态转移模型是指操作系统在管理进程时,将进程的状态划分为五个不同的状态,并通过这些状态之间的转移来控制进程的执行。这些状态包括:

  1. 创建态(New):表示一个新的进程正在被创建,此时操作系统已经为该进程分配了所需的资源,但还没有开始执行。

  2. 就绪态(Ready):表示进程已经准备好运行,等待CPU的分配。

  3. 运行态(Running):表示CPU正在执行某一进程的代码。

  4. 阻塞态(Blocked):表示进程由于某种原因无法继续执行,例如等待输入输出、等待信号量等。

  5. 终止态(Terminated):表示进程已经执行完毕或者因为某种原因被强制终止,此时进程的所有资源都需要被释放。

在这个模型中,进程会从一个状态转移到另一个状态,具体的转移方式如下:

  1. 从创建态到就绪态:当操作系统为一个进程分配了所有必要的资源之后,该进程就会从新建态转移到就绪态,等待CPU的分配。

  2. 从就绪态到运行态:当CPU空闲时,操作系统会从就绪队列中选择一个进程并将其分配给CPU执行。

  3. 从运行态到就绪态:当一个进程的时间片用完或者等待某个事件发生时,该进程会被调度到就绪队列中等待下一次CPU分配。

  4. 从运行态到阻塞态:当一个进程需要等待某个事件发生时,例如等待输入输出或等待信号量,它会被移动到阻塞队列中等待事件发生。

  5. 从阻塞态到就绪态:当一个进程所等待的事件发生后,操作系统会将其从阻塞队列中移除,并将其放回到就绪队列中等待CPU分配。

  6. 从运行态到终止态:当一个进程执行完毕或者出现错误时,它会被强制终止,并移动到终止态。此时,操作系统会释放该进程占用的所有资源。

以上就是进程的五状态转移模型以及每个状态之间的转移方式。

信号量机制

记录型信号量

(1)P操作中,一定是先value--,之后可能执行block原语;

(2)V操作中,一定是先value++,之后可能执行wakeup原语;

(3)能够判断在什么条件下需要执行block或者wakeup。

PV操作实例分析(☆☆)

生产者与消费者问题

生产者-消费者问题是一个经典的并发同步与互斥问题,涉及到多个线程之间的协作。该问题中有两种角色:生产者和消费者,它们共享一个缓冲区。生产者向缓冲区中添加数据,而消费者从缓冲区中取出数据。

下面是一个简单的使用伪代码实现的PV操作示例:

Semaphore mutex = 1; // 互斥信号量
Semaphore empty = n; // 缓存区空闲数信号量
Semaphore full = 0; // 缓存区已占用数信号量

// 生产者进程代码
do {
    // 生产数据
    ...
    P(empty); // 申请空闲缓存区
    P(mutex); // 申请访问缓存区的互斥权
    // 将数据放入缓存区
    ...
    V(mutex); // 释放访问缓存区的互斥权
    V(full); // 增加缓存区已占用数
} while (true);

// 消费者进程代码
do {
    P(full); // 申请已占用缓存区
    P(mutex); // 申请访问缓存区的互斥权
    // 从缓存区取出数据
    ...
    V(mutex); // 释放访问缓存区的互斥权
    V(empty); // 增加空闲缓存区
} while (true);

在这个示例中,mutex、empty和full分别为三个信号量,表示互斥、空闲缓存区数和已占用缓存区数。生产者在申请空闲缓存区时需要使用P(empty)操作,如果没有空闲缓存区则会被阻塞;在访问缓存区时需要使用P(mutex)操作获取互斥权,避免多个生产者同时访问导致冲突。消费者在申请已占用缓存区时需要使用P(full)操作,如果没有已占用缓存区则会被阻塞;在访问缓存区时同样需要使用P(mutex)操作获取互斥权。

生产者与消费者的变形问题

问题情形:桌上有一空盘,允许存放一只水果。爸爸可向盘中放苹果,也可向盘中放桔子,儿子专等吃盘中的桔子,女儿专等吃盘中的苹果。规定当盘空时一次只能放一只水果供吃者取用,请用P、V原语实现爸爸、儿子、女儿三个并发进程的同步。

这个问题可以使用生产者-消费者模型来解决。其中爸爸作为生产者,将水果放入盘中;女儿和儿子作为消费者,从盘中取出自己所需的水果。

Semaphore mutex = 1; // 互斥信号量
Semaphore empty = 1; // 缓存区空闲数信号量
Semaphore apple = 0; // 盘中苹果数信号量
Semaphore orange = 0; // 盘中桔子数信号量

// 爸爸进程代码
do {
    // 生产水果
    ...
    P(empty); // 申请空闲缓存区
    P(mutex); // 申请访问缓存区的互斥权
    if (fruit == APPLE) {
        V(apple); // 增加盘中苹果数
    } else {
        V(orange); // 增加盘中桔子数
    }
    V(mutex); // 释放访问缓存区的互斥权
} while (true);

// 女儿进程代码
do {
    P(apple); // 申请盘中苹果
    P(mutex); // 申请访问缓存区的互斥权
    // 从盘中拿走苹果
    ...
    V(mutex); // 释放访问缓存区的互斥权
    V(empty); // 增加空闲缓存区
    // 消费苹果
    ...
} while (true);

// 儿子进程代码
do {
    P(orange); // 申请盘中桔子
    P(mutex); // 申请访问缓存区的互斥权
    // 从盘中拿走桔子
    ...
    V(mutex); // 释放访问缓存区的互斥权
    V(empty); // 增加空闲缓存区
    // 消费桔子
    ...
} while (true);

在这个示例中,mutex、empty、apple和orange分别为四个信号量,表示互斥、空闲缓存区数、盘中苹果数和盘中桔子数。爸爸在申请空闲缓存区时需要使用P(empty)操作,如果没有空闲缓存区则会被阻塞;在访问缓存区时需要使用P(mutex)操作获取互斥权,避免多人同时访问导致冲突。女儿和儿子在申请盘中水果时需要使用P(apple)和P(orange)操作,如果盘中没有对应的水果则会被阻塞;在访问缓存区时同样需要使用P(mutex)操作获取互斥权。

有任何问题,请在博客下方留言。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值