假设有一座独木桥,同一方向的行人可以连续过桥,而当某一方向有人过桥时,另一方向的行人必须等待;直到某一方向无人过桥时,另一方向的行人才可以过桥。用信号量解决该同步互斥问题,其中初始条件设置和其中一方行人的进程代码如下,补全代码中的空白。(每空计1分)
int ACounter = 0;
int BCounter = 0; //ACounter和BCounter分别表示从A、B两方向过桥的人数
semaphore bridge = (空白1); //实现对桥的互斥共享
semaphoreAMutex = BMutex = (空白2); //对Acounter和BCounter的互斥共享
PA(){
wait(AMutex);
if (ACounter == (空白3)) wait ((空白4));
(空白5);
signal((空白6));
使用浴室;
wait(AMutex);
ACounter--;
if(ACounter == 0)signal(bridge);
signal((空白7));
}
//PB()进程与PA()进程类似,只需将“A”与“B”互换
我引用ChatGPT作答:
int ACounter = 0;
int BCounter = 0; //ACounter和BCounter分别表示从A、B两方向过桥的人数
semaphore bridge = (1); //实现对桥的互斥共享
semaphore AMutex = 1, BMutex = 1; //对ACounter和BCounter的互斥共享
PA(){
wait(AMutex);
if (ACounter == 0) wait(bridge);
ACounter++;
signal(AMutex);
使用浴室;
wait(AMutex);
ACounter--;
if (ACounter == 0) signal(bridge);
signal(AMutex);
}
//PB()进程与PA()进程类似,只需将“A”与“B”互换
PB(){
wait(BMutex);
if (BCounter == 0) wait(bridge);
BCounter++;
signal(BMutex);
使用浴室;
wait(BMutex);
BCounter--;
if (BCounter == 0) signal(bridge);
signal(BMutex);
}
初始条件:ACounter = 0, BCounter = 0,bridge信号量初值为1,AMutex和BMutex信号量初值为1。
int ACounter = 0;
int BCounter = 0;
semaphore bridge = semaphore(1); //实现对桥的互斥共享
semaphore AMutex = semaphore(1); //对ACounter的互斥共享
semaphore BMutex = semaphore(1); //对BCounter的互斥共享
PA(){
wait(AMutex);
if (ACounter == 0) wait (bridge);
ACounter++;
signal(AMutex);
(过桥操作);
wait(bridge);
使用浴室;
wait(AMutex);
ACounter--;
if(ACounter == 0)signal(bridge);
signal(AMutex);
}
//PB()进程与PA()进程类似,只需将“A”与“B”互换
解释:
bridge 是一个二元信号量,用于实现对桥的互斥共享。初始时,它被初始化为 1,表示桥是空闲的。
AMutex 和 BMutex 是二元信号量,用于对 ACounter 和 BCounter 的互斥共享。初始时,它们被初始化为 1,表示这两个计数器是空闲的。
PA() 进程和 PB() 进程非常相似,只是在检查计数器和加减计数器时使用不同的变量名。
在进入桥之前,进程需要获得对应的 AMutex 或 BMutex。如果桥已经被另一个方向的行人占用,进程需要等待直到桥空闲。
在离开桥之前,进程需要释放对应的 AMutex 或 BMutex,并检查是否还有其他方向的行人正在桥上。如果没有,它需要释放 bridge,使得等待的行人可以进入桥。
值得注意的是:
对于二维数组例如: a[2][2]
a表示的整个数组的首地址,a[0]表示的是第一行的首地址,这两者者在数值上是一样的,但含义不同(或者说类型不同),数组名a是对于整个数组(类型为int(*)[2] )
,a[0]是对于第一行(类型为 int* )
二维数组的解引用(以二维数组a为例)
*(*(a + i) + j)相当于a[i][j]
#include<stdio.h>
#include<stdlib.h>
#define N 5
void swop(int* a, int* b) {//交换两个数,两个形参为指针
*a = *a ^ *b;
*b = *a ^ *b;
*a = *a ^ *b;
}
void fun(int(*p)[N]){
int* max = (int*)p;//最大值
int* min1 = (int*)p;//最小值
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
if (*max < *(*(p + i) + j)) {
max = *(p + i) + j;
}
if (*min1 > *(*(p + i) + j)) {
min1 = *(p + i) + j;
}
}
}
int* min2 = *(p + 2) + 2;//次小值
int* min3 = *(p + 2) + 2; //倒数第三小值
int* min4 = *(p + 2) + 2;//倒数第四小值
swop(max, *(p + 2) + 2);//最大值与中间的值交换
swop(min1, *p);//最小值与左上角的值交换
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
if (*(p + i) + j == *p) {
continue;
}
if (*min2 > *(*(p + i) + j)) {
min2 = *(p + i) + j;
}
}
}
swop(min2, *(p)+N - 1);//次小值与右上角的值交换
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
if (*(p + i) + j == *p || *(p + i) + j ==*(p)+N - 1) {
continue;
}
if (*min3 > *(*(p + i) + j)) {
min3 = *(p + i) + j;
}
}
}
swop(min3, *(p + N - 1));//倒数第三小值与左下角的值交换
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
if (*(p + i) + j == *p || *(p + i) + j == *(p)+N - 1 || *(p + i) + j == *(p + N - 1)) {
continue;
}
if (*min4 > *(*(p + i) + j)) {
min4 = *(p + i) + j;
}
}
}
swop(min4, *(p + N - 1) + N - 1); //倒数第四小值右下角的值交换
}
void main() {
int arr[N][N];
int(*p)[N] = arr;//定义指向二维数组的指针p
int count = 25;
for (int i = 0; i < N; ++i) {//初始化二维数组
for (int j = 0; j < N; ++j) {
*(*(p + i) + j) = count;
count -= 1;
}
}
printf("原数组为\n");
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
printf("%d\t", *(*(p + i) + j));
}
printf("\n");
}
printf("\n\n转换后的数组为\n");
fun(p);
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
printf("%d\t", *(*(p + i) + j));
}
printf("\n");
}
system("pause");
}
int ACounter = 0;
int BCounter = 0;
semaphore bridge = 1; //实现对桥的互斥共享
semaphore AMutex = 1;
semaphore BMutex = 1; //对Acounter和BCounter的互斥共享
PA(){
wait(AMutex);
if (ACounter == 0) wait (bridge);
ACounter++;
signal(AMutex);
//使用浴室;
wait(AMutex);
ACounter--;
if(ACounter == 0)signal(bridge);
signal(AMutex);
}
PB(){
wait(BMutex);
if (BCounter == 0) wait (bridge);
BCounter++;
signal(BMutex);
//使用浴室;
wait(BMutex);
BCounter--;
if(BCounter == 0)signal(bridge);
signal(BMutex);
}