计算机操作系统问题,各位

假设有一座独木桥,同一方向的行人可以连续过桥,而当某一方向有人过桥时,另一方向的行人必须等待;直到某一方向无人过桥时,另一方向的行人才可以过桥。用信号量解决该同步互斥问题,其中初始条件设置和其中一方行人的进程代码如下,补全代码中的空白。(每空计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,使得等待的行人可以进入桥。

  • 你可以参考下这个问题的回答, 看看是否对你有帮助, 链接: https://ask.csdn.net/questions/382
  • 除此之外, 这篇博客: (C语言)将一个5乘5矩阵中最大的数放在中心,四个角分别放4个最小的元素(顺序为从左到右,从上到下依次从小到大存放),写一函数实现,在面函数中调用(指针的方法处理)中的 将一个5乘5矩阵中最大的数放在中心,四个角分别放4个最小的元素(顺序为从左到右,从上到下依次从小到大存放),写一函数实现,在面函数中调用(指针的方法处理) 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 值得注意的是:
    对于二维数组例如: 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");
    }
    
    
    

    在这里插入图片描述

该回答引用ChatGPT
这是一个经典的同步互斥问题,可以使用信号量来解决。以下是代码的补全:

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);
}

解释如下:
1. `bridge` 信号量用于实现对桥的互斥共享,初始值为 1,表示桥是空闲的。
2. `AMutex` 和 `BMutex` 信号量用于对 `ACounter` 和 `BCounter` 的互斥共享,初始值为 1,表示只有一个进程可以访问计数器。
3. `PA()` 进程的代码中,首先使用 `wait(AMutex)` 获取对 `ACounter` 的互斥访问,然后判断是否有人从 A 方向过桥,如果没有,则使用 `wait(bridge)` 等待桥空闲。接着,将 `ACounter` 加 1,表示有一个人从 A 方向过桥。最后,释放对 `AMutex` 的访问,使用浴室,再次获取对 `AMutex` 的访问,将 `ACounter` 减 1,表示一个人从 A 方向过桥完成。如果此时没有人从 A 方向过桥了,使用 `signal(bridge)` 释放桥的使用权。
4. `PB()` 进程的代码与 `PA()` 进程类似,只需将 A 和 B 互换即可。
需要注意的是,这里的代码只是一个简单的示例,实际应用中可能需要更加复杂的同步互斥机制来保证正确性。