题目背景
假设系统中有三个进程 P1、P2、P3 和一个共享缓冲区 B,缓冲区容量为 N。进程 P1 不断生成正整数并放入缓冲区;若生成的数为奇数,则由 P2 从缓冲区取出并打印;若为偶数,则由 P3 取出并打印。要求设计同步算法,确保进程正确协作且不发生死锁。
Java实现思路
1. 问题分析
-
同步需求:
-
互斥访问:缓冲区 B 是临界资源,同一时间只能有一个进程访问。
-
生产者-消费者关系:P1 为生产者,P2/P3 为消费者,需通过信号量控制缓冲区空位和数据的奇偶性。
-
-
信号量设计:
-
mutex:互斥信号量(初始值为1),保护缓冲区访问。 -
empty:缓冲区空位数量(初始值为N)。 -
odd:奇数数据可消费数量(初始值为0)。 -
even:偶数数据可消费数量(初始值为0)。
-
2. Java代码实现
import java.util.concurrent.Semaphore;
public class ProcessSynchronization {
static final int N = 10; // 缓冲区容量
static int[] buffer = new int[N]; // 共享缓冲区
static int in = 0, out = 0; // 缓冲区指针
// 定义信号量
static Semaphore mutex = new Semaphore(1); // 互斥访问缓冲区
static Semaphore empty = new Semaphore(N); // 空位数量
static Semaphore odd = new Semaphore(0); // 奇数数据可消费数量
static Semaphore even = new Semaphore(0); // 偶数数据可消费数量
// 进程P1:生产者
static class P1 extends Thread {
@Override
public void run() {
try {
for (int i = 1; i <= 20; i++) { // 模拟生成20个数
empty.acquire(); // 等待空位
mutex.acquire(); // 互斥访问缓冲区
buffer[in] = i;
System.out.println("P1生成: " + i);
in = (in + 1) % N;
mutex.release(); // 释放缓冲区
if (i % 2 == 1) odd.release(); // 奇数通知P2
else even.release(); // 偶数通知P3
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// 进程P2:奇数消费者
static class P2 extends Thread {
@Override
public void run() {
try {
while (true) {
odd.acquire(); // 等待奇数数据
mutex.acquire();
int num = buffer[out];
System.out.println("P2取出奇数: " + num);
out = (out + 1) % N;
mutex.release();
empty.release(); // 释放空位
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// 进程P3:偶数消费者
static class P3 extends Thread {
@Override
public void run() {
try {
while (true) {
even.acquire(); // 等待偶数数据
mutex.acquire();
int num = buffer[out];
System.out.println("P3取出偶数: " + num);
out = (out + 1) % N;
mutex.release();
empty.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new P1().start();
new P2().start();
new P3().start();
}
}
关键逻辑解析
-
信号量控制:
-
empty:确保缓冲区不满时 P1 才能写入。 -
odd/even:根据数据奇偶性唤醒对应的消费者(P2 或 P3)。 -
mutex:保证缓冲区的原子操作,避免数据竞争。
-
-
环形缓冲区管理:
-
in和out指针循环移动,模拟有限缓冲区的环形结构。
-
-
线程安全与死锁避免:
-
按顺序获取信号量(先
empty后mutex),避免因顺序错误导致的死锁。 -
消费者通过
odd和even信号量区分任务,实现精准唤醒。
-
扩展思考
-
性能优化:可引入多生产者或多消费者模型,进一步模拟复杂场景。
-
异常处理:增加超时机制或中断响应,处理线程阻塞问题。
-
动态调整:根据系统负载动态调整缓冲区大小(如使用
BlockingQueue替代数组)。
真题考点关联
-
进程同步机制:通过信号量实现互斥与条件同步,是操作系统调度算法的核心。
-
临界区管理:展示如何通过代码实现互斥访问,呼应“并发与共享是操作系统基本特征”的理论。
-
生产者-消费者模型:经典同步问题的变种,考察对资源分配与调度的理解。
1073

被折叠的 条评论
为什么被折叠?



