26-OS-PV大题

✅ 生产消费者

六步骤:

一、明确进程分类

确定有几类进程,每类进程对应一个函数 ,清晰区分不同角色(如生产者、消费者,或案例里的 “同学、大师傅” )。

二、描述进程动作

在进程函数内部,用中文描述核心行为:

  • 若动作 “只做一次”,不加while(1)循环;
  • 若动作 “不断重复”,用while(1)包裹逻辑。

三、分析 PV 操作

梳理进程动作前是否需P操作(申请资源 / 锁):

  • 只要用P(申请),必须配对V(释放),保证资源 / 信号量正确回收;
  • 注意 “隐含互斥”,比如操作临界资源(共享变量、设备),需加P(mutex)等互斥信号量。

四、定义信号量

所有P/V逻辑写完后,再定义信号量(如Semaphore类型),并确定初始值

  • 需结合资源初始状态(如 “rice=0 、 one=100” ,根据生产 / 消费逻辑设置 )。

五、检查死锁风险

重点看连续P操作

  • 若多个P连续出现,尝试调整顺序,避免循环等待;
  • 若某信号量P/V“连续且无其他P插入”,因不破坏 “请求和保持”,一般不会死锁。

六、验证题目要求

最后读题复盘:确认进程逻辑、PV 配对、资源交互是否贴合题目场景(如生产消费流程、资源数量约束等 ),保证模型满足需求。

核心逻辑:通过 “分类→动作→PV→信号量→死锁→验证” 六步,逐步搭建进程同步模型,用 PV 操作解决 “生产 - 消费” 的资源协调问题,同时规避死锁风险 。

✅ 同步问题和生产消费同时完成:

定义五类:

// 进程A:独立执行,完成后释放信号量通知后续进程
A() {
    操作A;                  // 进程A的核心任务(无前置依赖)
    V(A完成);              // A执行完毕,释放" A完成 "信号量(值+1)
}

// 进程B:独立执行,完成后释放信号量通知后续进程
B() {
    操作B;                  // 进程B的核心任务(无前置依赖)
    V(B完成);              // B执行完毕,释放" B完成 "信号量(值+1)
}

// 进程C:依赖A和B完成后才能执行
C() {
    P(A完成);              // 等待A执行完毕(若A未完成则阻塞)
    P(B完成);              // 等待B执行完毕(若B未完成则阻塞)
    操作C;                  // 只有A和B都完成后,才能执行C的任务
    V(C完成);              // C执行完毕,释放" C完成 "信号量(值+1)
}

// 进程D:独立执行,完成后释放信号量通知后续进程
D() {
    操作D;                  // 进程D的核心任务(无前置依赖)
    V(D完成);              // D执行完毕,释放" D完成 "信号量(值+1)
}

// 进程E:依赖C和D完成后才能执行
E() {
    P(C完成);              // 等待C执行完毕(若C未完成则阻塞)
    P(D完成);              // 等待D执行完毕(若D未完成则阻塞)
    操作E;                  // 只有C和D都完成后,才能执行E的任务
}

✅ 哲学家进餐(只有一种资源才能运行)

操作模板:使用int变量表示资源

// 定义互斥大锁(用于资源操作的同步)
semaphore Lock = 1; 

// 定义各类资源的剩余数量
int a = 9;  // 资源a剩余数量
int b = 8;  // 资源b剩余数量
int c = 5;  // 资源c剩余数量

Process() {
    while(1) {
        P(Lock);  // 申请锁,进入临界区
        
        // 检查所需资源是否充足
        if(所有资源都满足需求) {
            // 按需求减少对应资源的剩余数量
            各类资源int--;  // 具体减少数量根据题目要求确定
            
            // 一次性获取所有所需资源
            取对应资源;
            
            V(Lock);  // 释放锁,退出临界区
            break;    // 成功获取资源,跳出循环
        }
        
        V(Lock);  // 资源不足,释放锁,等待下次尝试
    }
    
    // 执行进程的核心任务(例如:哲学家进餐)
    做进程该做的事;
    
    P(Lock);  // 申请锁,进入临界区
    // 一次性归还所有资源,恢复资源剩余数量
    各类资源int++;  // 归还数量与之前获取的数量一致
    V(Lock);  // 释放锁,退出临界区
}

✅ 顾客-服务员并发模型(含忙等 / 睡觉 / 限制)

本模型模拟服务员与顾客之间的并发关系,通过 信号量机制 实现同步,同时 限制顾客数量,控制系统资源使用,防止过载。


🔧 代码实现(含注释)

👥 顾客线程 customer_i()

customer_i() {
    P(mutex);              // 取号(进入临界区)

    if (waiting >= MAX) {  // 如果顾客太多
        V(mutex);          // 离开前释放mutex
        return;            // 顾客离开
    }

    取号;
    waiting++;             // 顾客数+1
    V(mutex);              // 离开临界区

    等待被叫号;
    V(customer);           // 通知服务员有顾客到达
    P(service);            // 等待服务员叫号
    被服务;
}

👨‍🔧 服务员线程 server_i()

server_i() {
    while (1) {

        P(mutex);          // 进入临界区
        if (waiting > 0) {
            叫号;
            waiting--;     // 顾客数-1
            V(mutex);      // 离开临界区

            // 提供服务
            V(service);    // 通知顾客可以被服务了

        } else {
            V(mutex);      // 无顾客,释放锁
            P(customer);   // 睡觉(阻塞)
        }
    }
}

✅ 三个关键行为总结


1️⃣ 服务人员是忙等(✅ 是)

while (1) {
    P(mutex);
    if (waiting > 0) {
        ...
    } else {
        V(mutex);
        // ❌ 没有阻塞操作
    }
}
📌 说明:
  • 服务员每次循环都 主动抢占 mutex,检查 waiting 值。

  • 即使没有顾客,也会进入临界区检查再决定是否休眠。

  • 所以不是完全阻塞等待,而是“忙等 + 条件阻塞”的组合。

✅ 结论:

服务员不是被动等待,而是持续检查顾客状态,属于忙等行为(Busy Waiting)


2️⃣ 服务人员会睡觉(✅ 是)

等待被叫号;
V(customer);           // 通知服务员有顾客到达



P(customer); // 无顾客时阻塞
📌 说明:
  • waiting == 0 时,服务员执行 P(customer),线程会阻塞。

  • 直到有顾客调用 V(customer) 才能唤醒服务员。

  • 这是一种节省 CPU 的阻塞睡眠机制,模拟现实中“服务员打盹”。

✅ 结论:

服务员在无顾客时会“睡觉”,等待被顾客唤醒,符合并发控制设计。


3️⃣ 顾客数有限(✅ 是)

if (waiting >= MAX) {
    V(mutex);
    return;
}
📌 说明:
  • 通过 if (waiting >= MAX) 判断是否已超出等候限制。

  • 如果等候人数已满,顾客释放 mutex 后离开。

  • 实现了类似“座位数有限”的约束,控制资源使用。

✅ 结论:

顾客数受限,模拟“座位有限”现实逻辑,防止系统过载。

📌 最终总结表格(最新版)

特性名称是否实现说明
服务人员是忙等✅ 是服务员每轮循环都执行 P(mutex) 并检查 waiting,不是被动等待顾客唤醒,有忙等行为。
服务人员会睡觉✅ 是如果没有顾客,服务员最终会进入 P(customer) 阻塞状态,模拟“打盹”行为。
顾客有座位限制✅ 是waiting >= MAX,顾客立即离开,不再加入队列,模拟座位已满的情况。

🧠 结语总结一句话:

本并发模型通过信号量和互斥锁机制控制顾客与服务员的同步,具备“有限排队忙等检查空闲可睡”三种典型行为,适合理解操作系统中的线程同步问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大大大大小小

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值