操作系统临界区互斥软件实现基本方法
·
2026.9.8
第一版 C语言实现
这一版确实成功实现了各个算法,但思路混乱,没有将检查与各个进程本身分离,所有检查由各进程自己实现,无法精细调整各代码段的执行顺序,难以对各个算法进行完整测试。
#include <stdio.h>
#include <stdbool.h>
#ifndef OK
#define OK 1
#endif // !OK
#ifndef ERROR
#define ERROR 0
#endif // !ERROR
typedef int Status;
bool flag[2] = { false };
int critical_resource = -1;
int turn = -1;
enum choice
{
singleSign,doubleSignFirst,doubleSignAfter,Peterson
};
void menu(void);
Status singleSignP0(void);
Status singleSignP1(void);
Status doubleSignFirstP0(void);
Status doubleSignFirstP1(void);
Status doubleSignAfterP0(void);
Status doubleSignAfterP1(void);
Status PetersonP0(void);
Status PetersonP1(void);
int main(void)
{
while (true)
{
menu();
enum choice ch;
fputs("请选择要测试的算法:", stdout);
while (!scanf_s("%d", &ch) || ch < 0 || ch > 4)
{
while ((ch = getchar()) != '\n');//清理输入的错误字符
fprintf(stderr, "输入错误,请重新输入:");
}
putchar('\n');
ch--;
switch (ch)
{
case singleSign:
turn = 0;
singleSignP0();
singleSignP1();
singleSignP1();
break;
case doubleSignFirst:
doubleSignFirstP0();
doubleSignFirstP1();
doubleSignFirstP1();
break;
case doubleSignAfter:
doubleSignAfterP0();
doubleSignAfterP1();
doubleSignAfterP1();
break;
case Peterson:
PetersonP0();
PetersonP1();
PetersonP1();
break;
}
putchar('\n');
}
return 0;
}
void menu(void)
{
fputs("1.单标志法\t\t2.双标志先检查法\n"
"3.双标志后检查法\t4.Peterson算法\n", stdout);
}
Status singleSignP0(void)
{
puts("P0尝试进入临界区");
if (turn != 0)
printf("turn=%d,P0循环等待\n", turn);
//while (turn != 0);//进入区
puts("P0进入临界区");
critical_resource = 0;//临界区
turn = 1;//退出区
puts("P0退出临界区!");//剩余区
return OK;
}
Status singleSignP1(void)
{
puts("P1尝试进入临界区");
if (turn != 1)
printf("turn=%d,P1循环等待\n", turn);
//while (turn != 1);//进入区
puts("P1进入临界区");
critical_resource = 1;//临界区
turn = 0;//退出区
puts("P1退出临界区!");//剩余区
return OK;
}
Status doubleSignFirstP0(void)
{
while (flag[1]);//进入区
flag[0] = true;//进入区
puts("P0进入临界区");
critical_resource = 0;//临界区
flag[0] = false;//退出区
puts("P0退出临界区!");//剩余区
return OK;
}
Status doubleSignFirstP1(void)
{
while (flag[0]);//进入区
flag[1] = true;//进入区
puts("P1进入临界区");
critical_resource = 1;//临界区
flag[1] = false;//退出区
puts("P1退出临界区!");//剩余区
return OK;
}
Status doubleSignAfterP0(void)
{
flag[0] = true;//进入区
while (flag[1]);//进入区
puts("P0进入临界区");
critical_resource = 0;//临界区
flag[0] = false;//退出区
puts("P0退出临界区!");//剩余区
return OK;
}
Status doubleSignAfterP1(void)
{
flag[1] = true;//进入区
while (flag[0]);//进入区
puts("P1进入临界区");
critical_resource = 1;//临界区
flag[1] = false;//退出区
puts("P1退出临界区!");//剩余区
return OK;
}
Status PetersonP0(void)
{
flag[0] = true;//进入区
turn = 1;//进入区
while (flag[1] && turn == 1);//进入区
puts("P0进入临界区");
critical_resource = 0;//临界区
flag[0] = false;//退出区
puts("P0退出临界区!");//剩余区
return OK;
}
Status PetersonP1(void)
{
flag[1] = true;//进入区
turn = 0;//进入区
while (flag[0] && turn == 0);//进入区
puts("P1进入临界区");
critical_resource = 1;//临界区
flag[1] = false;//退出区
puts("P1退出临界区!");//剩余区
return OK;
}
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)