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

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐