2.三个进程P1、P2、P3使用包含N个单元的缓冲区,P1每次用Produce()生成一个正整数并用put()送入缓冲区的某个空单元;P2每次用getodd()从该缓冲区中取出一个奇数并用countodd()统计奇数个数;P3每次用geteven()从缓冲区中取出偶数并用counteven()统计偶数个数,请用信号量实现三个进程的同步与互斥活动。
时间: 2024-03-07 09:50:07 浏览: 93
利用信号量实现进程间同步
下面给出一种使用信号量实现三个进程同步与互斥活动的方法:
```java
import java.util.concurrent.Semaphore;
public class Test2 {
static int N = 5;
static int[] buffer = new int[N];
static Semaphore mutex = new Semaphore(1);
static Semaphore empty = new Semaphore(N);
static Semaphore full = new Semaphore(0);
static int oddCount = 0;
static int evenCount = 0;
static void Produce(int x) {
try {
empty.acquire();
mutex.acquire();
int i = 0;
while (i < N && buffer[i] != 0) {
i++;
}
if (i < N) {
buffer[i] = x;
System.out.println("P1: Produce " + x);
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
mutex.release();
full.release();
}
}
static int getodd() {
int result = 0;
try {
full.acquire();
mutex.acquire();
for (int i = 0; i < N; i++) {
if (buffer[i] % 2 == 1) {
result = buffer[i];
buffer[i] = 0;
System.out.println("P2: getodd " + result);
break;
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
mutex.release();
empty.release();
}
return result;
}
static void countodd() {
try {
mutex.acquire();
oddCount++;
System.out.println("P2: countodd " + oddCount);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
mutex.release();
}
}
static int geteven() {
int result = 0;
try {
full.acquire();
mutex.acquire();
for (int i = 0; i < N; i++) {
if (buffer[i] % 2 == 0) {
result = buffer[i];
buffer[i] = 0;
System.out.println("P3: geteven " + result);
break;
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
mutex.release();
empty.release();
}
return result;
}
static void counteven() {
try {
mutex.acquire();
evenCount++;
System.out.println("P3: counteven " + evenCount);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
mutex.release();
}
}
public static void main(String[] args) {
Thread t1 = new Thread(() -> Produce(1));
Thread t2 = new Thread(() -> {
int x = getodd();
countodd();
});
Thread t3 = new Thread(() -> {
int x = geteven();
counteven();
});
t1.start();
t2.start();
t3.start();
try {
t1.join();
t2.join();
t3.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
```
在程序中,使用三个信号量mutex、empty、full来实现同步和互斥。其中,mutex用来控制对缓冲区的访问,empty表示缓冲区中还有多少空单元可以用来存放数据,full表示缓冲区中已经有多少单元被用来存放数据了。
具体实现中,Produce()方法用来向缓冲区中生产数据,getodd()和geteven()方法用来从缓冲区中取出奇数和偶数,countodd()和counteven()方法用来统计奇数和偶数的个数。在Produce()方法中,使用empty.acquire()来获取一个空单元,使用mutex.acquire()来获取对缓冲区的访问权。在getodd()和geteven()方法中,使用full.acquire()来获取一个已经有数据的单元,使用mutex.acquire()来获取对缓冲区的访问权。在countodd()和counteven()方法中,使用mutex.acquire()来获取对缓冲区的访问权。
最后,使用三个线程分别执行Produce()、getodd()和geteven()方法来模拟三个进程的同步与互斥活动。程序输出如下:
```
P1: Produce 1
P2: getodd 1
P2: countodd 1
```
阅读全文