操作系统课程设计 ——进程调度

操作系统课程设计 ——进程调度

#include 
#include 
#include 


/*临资源定义区*/





#define keyboard 0 //设置键盘这一临界资源为device[0]

#define mouse 1  //设置鼠标这一临界资源为device[1]

#define printer 2  //设置打印机这一临界资源为device[2]




/*



						数据结构区


*/
struct PCB//PCB块结构体(待完善)
{
	char name[20];//进程名称
	int state = 0;//表示PCB单元的状态(空闲0,就绪1,执行2)态
	int server_time = 0;//进程服务时间
	int ready_time = 0;//PCB处于就绪队列中则此项为等待时间
	int block_time = 0;//PCB处于阻塞队列中此项为剩余等待时间
	int device[5];//表示临界资源
	struct PCB* next = NULL;//下一PCB节点
}PCBS[10];//声明PCB块队列

struct semaphore//信号量结构体
{
	int value = 0;
	struct PCB* next = NULL;
} semaphores[10];//数组大小为临界资源数量


struct PCB* free_listHEAD = &PCBS[0];//空闲PCB队列头指针

struct PCB* free_listTAIL = &PCBS[9];//空闲PCB队列尾指针

struct PCB* ready_listHEAD = NULL;//就绪队列头指针

struct PCB* ready_listTAIL = NULL;//就绪队列尾指针

struct PCB* running = NULL;//执行队列头指针

struct PCB* wait_listHEAD = NULL;//阻塞队列头指针

struct PCB* wait_listTAIL = NULL;//阻塞队列尾指针


void chain_append(struct PCB* temp, struct PCB** chain_head_point, struct PCB** chain_tail_point, int state);//将指定节点,加入到指定链表尾部,指定更改状态


void chain_appendInit(struct PCB* temp, struct PCB** chain_head_point, struct PCB** chain_tail_point);//将指定节点,初始化后加入到指定链表尾部


struct PCB* chain_pop(struct PCB** chain_head_point, struct PCB** chain_tail_point);


struct PCB* chain_delByName(char name[], struct PCB** chain_head_point, struct PCB** chain_tail_point);//删除链表中指定名称的进程,若删除成功则返回指针,若删除不成功则返回NULL


struct PCB* chain_delByPointer(struct PCB* targetpointer, struct PCB** chain_head_point, struct PCB** chain_tail_point);


struct PCB* chain_DoForEach(struct PCB** chain_head_point, struct PCB** chain_tail_point, int statue);


int check_doing();//检测是否有进程在执行,若没有则将执行就绪队列进程


struct PCB* block_process(int time);//阻塞当前正在执行的进程,并将其加入到阻塞队列中


void cancel_process(char name[]);//撤销就绪队列或阻塞队列中的进程


void re_processByName(char name[]);//通过名称把阻塞态恢复到就绪态


void re_processByPointer(struct PCB* targetpointer);//通过指针将阻塞态恢复到就绪态


int create_process(char name[], int server_time);//创建进程函数


void show_process(struct PCB* free_list, struct PCB* ready_list, struct PCB* wait_list);//将目前系统内的所有进程队列(包括就绪,空闲,执行态)全部打印出来


void show_single_process(struct PCB* chain_head_point);



/*



					链表操作区




*/

void chain_append(struct PCB* temp, struct PCB** chain_head_point, struct PCB** chain_tail_point, int state)//将指定节点,加入到指定链表尾部,指定更改状态
{
	temp->state = state;
	if (*chain_head_point == NULL)
	{
		*chain_head_point = temp;
		*chain_tail_point = temp;
	}
	else
	{
		(*chain_tail_point)->next = temp;
		(*chain_tail_point) = (*chain_tail_point)->next;
	}
}

void chain_appendInit(struct PCB* temp, struct PCB** chain_head_point, struct PCB** chain_tail_point)//将指定节点,初始化后加入到指定链表尾部
{

	*temp->name = NULL;//对PCB进行初始化
	temp->server_time = 0;
	temp->next = NULL;
	temp->state = 0;
	temp->block_time = 0;
	temp->ready_time = 0;
	memset((*temp).device, 0, sizeof((*temp).device));


	if (*chain_head_point == NULL)
	{
		*chain_head_point = temp;
		*chain_tail_point = temp;
	}
	else
	{
		(*chain_tail_point)->next = temp;
		(*chain_tail_point) = (*chain_tail_point)->next;
	}
}

struct PCB* chain_pop(struct PCB** chain_head_point, struct PCB** chain_tail_point)
{
	struct PCB* temp = NULL;
	if (*chain_head_point == NULL)
	{
		printf("无空闲PCB或已空\n");
	}
	else
	{
		temp = *chain_head_point;
		if ((*chain_head_point)->next == NULL)
		{
			*chain_head_point = NULL;
			*chain_tail_point = NULL;
		}
		else
		{
			*chain_head_point = (*chain_head_point)->next;
		}
		temp->next = NULL;
	}

	return temp;
}

struct PCB* chain_delByName(char name[], struct PCB** chain_head_point, struct PCB** chain_tail_point)//删除链表中指定名称的进程,若删除成功则返回指针,若删除不成功则返回NULL
{
	if (*chain_head_point == NULL)
	{
		return NULL;
	}
	else
	{
		struct PCB* headpointer = *chain_head_point;
		struct PCB* pointer = *chain_head_point;
		if (!strcmp(name, pointer->name))//如果头节点是要找的进程
		{
			if (pointer->next == NULL)
			{
				*chain_head_point = NULL;
				*chain_tail_point = NULL;
			}
			else
			{
				*chain_head_point = (*chain_head_point)->next;
			}
			return pointer;
		}
		while (pointer != NULL && pointer->next != NULL)
		{
			if (!strcmp((pointer->next)->name, name))//如果找到相同名称的进程
			{
				struct PCB* temp = pointer->next;
				if ((pointer->next)->next == NULL)
				{
					pointer->next = NULL;
				}
				else
				{
					pointer->next = (pointer->next)->next;
				}
				return temp;
			}
			pointer = pointer->next;
		}

	}
	return NULL;
}
struct PCB* chain_delByPointer(struct PCB* targetpointer, struct PCB** chain_head_point, struct PCB** chain_tail_point)
{
	if (*chain_head_point == NULL)
	{
		*chain_tail_point = NULL;
		return NULL;
	}
	else
	{
		struct PCB* headpointer = *chain_head_point;
		struct PCB* pointer = *chain_head_point;
		if (pointer == targetpointer)//如果头节点是要找的进程
		{
			if (pointer->next == NULL)
			{
				*chain_head_point = NULL;
				*chain_tail_point = NULL;
			}
			else
			{
				*chain_head_point = (*chain_head_point)->next;
			}
			return pointer;
		}
		while (pointer != NULL && pointer->next != NULL)
		{
			if (pointer->next == targetpointer)//如果找到相同名称的进程
			{
				struct PCB* temp = pointer->next;
				if ((pointer->next)->next == NULL)
				{
					pointer->next = NULL;
				}
				else
				{
					pointer->next = (pointer->next)->next;
				}
				return temp;
			}
			pointer = pointer->next;
		}

	}
	return NULL;
}



/*以上为链表操作,不可直接调用已有的链表头尾指针*/





/*



		进程管理区



*/


int check_doing()//检测是否有进程在执行,若没有则将执行就绪队列进程
{
	if (running == NULL)
	{
		struct PCB* temp;
		temp = chain_pop(&ready_listHEAD, &ready_listTAIL);
		if (temp == NULL)
		{
			if (wait_listHEAD == NULL)
			{
				printf("CPU任务完成\n");
				return 2;//这种情况为系统无任务执行,完全空闲
			}
			else
			{
				printf("CPU正在闲逛\n");
				return 3;//这种情况为系统阻塞队列里仍有任务,但其他队列全部为空
			}
		}
		else
		{
			temp->ready_time = 0;
			chain_append(temp, &running, &running, 2);
			printf("装载完成\n");
			return 1;
		}
	}
	return 0;//这种情况为有程序在运行
}
/*
返回值状态:
0.现在有程序在运行
1.装载成功
2.cpu运行结束
3.等待阻塞队列进程结束阻塞
*/

struct PCB* block_process(int time)//阻塞当前正在执行的进程,并将其加入到阻塞队列中
{
	struct PCB* temp;
	temp = chain_pop(&running, &running);
	if (temp == NULL)
	{
		return NULL;
	}
	else
	{
		temp->block_time = time;
		chain_append(temp, &wait_listHEAD, &wait_listTAIL, 3);
		return temp;
	}
	check_doing();
}

void cancel_process(char name[])//撤销就绪队列或阻塞队列中的进程
{
	struct PCB* temp = NULL;

	if (temp == NULL)
	{
		temp = chain_delByName(name, &ready_listHEAD, &ready_listTAIL);
	}

	if (temp == NULL)
	{
		temp = chain_delByName(name, &wait_listHEAD, &wait_listTAIL);
	}

	if (temp == NULL)
	{
		printf("删除失败,请检查名称是否正确\n");
	}
	else
	{
		printf("删除成功!\n");
		chain_appendInit(temp, &free_listHEAD, &free_listTAIL);
	}
}


void re_processByName(char name[])//通过名称把阻塞态恢复到就绪态
{
	struct PCB* temp = NULL;
	temp = chain_delByName(name, &wait_listHEAD, &wait_listTAIL);
	if (temp == NULL)
	{
		printf("恢复失败,请检查名称是否正确\n");
	}
	else
	{
		
		temp->block_time = 0;
		chain_append(temp, &ready_listHEAD, &ready_listTAIL, 1);
		printf("恢复成功!\n");
	}
}

void re_processByPointer(struct PCB* targetpointer)//通过指针将阻塞态恢复到就绪态
{
	struct PCB* temp = NULL;
	if (targetpointer == NULL)
	{
		;
	}
	else
	{
		temp = chain_delByPointer(targetpointer, &wait_listHEAD, &wait_listTAIL);
	}
	if (temp== NULL)
	{
		printf("恢复失败,请检查名称是否正确\n");
	}
	else
	{
		temp->block_time = 0;
		chain_append(temp, &ready_listHEAD, &ready_listTAIL, 1);
		printf("恢复成功!\n");
	}
}


int create_process(char name[], int server_time)//创建进程函数!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!要使用的临界资源的整个流程没有实现
{
	int i;
	for (i = 0; i < 10; ++i)
	{
		if (!strcmp(name, PCBS[i].name))
		{
			printf("名称重复\n");
			return 0;
		}
	}
		struct PCB* temp;
		temp = chain_pop(&free_listHEAD, &free_listTAIL);
		if (temp == NULL)
		{
			return 0;
		}
		else
		{
			strcpy_s(temp->name, name);
			temp->server_time = server_time;
			/*

					在此处给新创建的进程赋值

			*/
			chain_append(temp, &ready_listHEAD, &ready_listTAIL, 1);
			return 1;
		}
		check_doing();
}
void show_process(struct PCB* free_list, struct PCB* ready_list, struct PCB* wait_list)//将目前系统内的所有进程队列(包括就绪,空闲,执行态)全部打印出来
{
	printf("PCB名称\tPCB状态\t服务时间\t等待时间\t阻塞时间\n");
	for (int i = 0; i < 10; ++i)
	{
		printf("%s\t%d\t%d\t%d\t%d\n", PCBS[i].name, PCBS[i].state, PCBS[i].server_time, PCBS[i].ready_time, PCBS[i].block_time);
	}
	printf("free_list///\n");
	while (free_list != NULL && free_list->next != NULL)
	{
		printf("%s\t%d\t%d\t%d\t%d\n", free_list->name, free_list->state, free_list->server_time, free_list->ready_time, free_list->block_time);
		free_list = free_list->next;
	}
	if (free_list != NULL)
	{
		printf("%s\t%d\n", free_list->name, free_list->state);
	}
	printf("ready_list///\n");
	while (ready_list != NULL && ready_list->next != NULL)
	{
		printf("%s\t%d\t%d\t%d\t%d\n", ready_list->name, ready_list->state, ready_list->server_time, ready_list->ready_time, ready_list->block_time);
		ready_list = ready_list->next;
	}
	if (ready_list != NULL)
	{
		printf("%s\t%d\t%d\t%d\t%d\n", ready_list->name, ready_list->state, ready_list->server_time, ready_list->ready_time, ready_list->block_time);
	}
	printf("wait_list///\n");
	while (wait_list != NULL && wait_list->next != NULL)
	{
		printf("%s\t%d\t%d\t%d\t%d\n", wait_list->name, wait_list->state,wait_list->server_time,wait_list->ready_time,wait_list->block_time);
		wait_list = wait_list->next;
	}
	if (wait_list != NULL)
	{
		printf("%s\t%d\t%d\t%d\t%d\n", wait_list->name, wait_list->state, wait_list->server_time, wait_list->ready_time, wait_list->block_time);
	}
	printf("running///\n");
	while (running != NULL && running->next != NULL)
	{
		printf("%s\t%d\t%d\t%d\t%d\n", running->name, running->state, running->server_time, running->ready_time, running->block_time);
		running = running->next;
	}
	if (running != NULL)
	{
		printf("%s\t%d\t%d\t%d\t%d\n", running->name, running->state, running->server_time, running->ready_time, running->block_time);
	}
}
void show_single_process(struct PCB* chain_head_point)
{
	printf("whatever///\n");
	while (chain_head_point != NULL && chain_head_point->next != NULL)
	{
		printf("%s\t%d\n", chain_head_point->name, chain_head_point->state);
		chain_head_point = chain_head_point->next;
	}
	if (chain_head_point != NULL)
	{
		printf("%s\t%d\n", chain_head_point->name, chain_head_point->state);
	}
}

struct PCB* chain_DoForEach(struct PCB** chain_head_point, struct PCB** chain_tail_point, int statue)
{
	if (*chain_head_point == NULL)
	{
		return NULL;
	}
	else
	{
		struct PCB* pointer = *chain_head_point;
		if (statue == 0)//使等待时间++
		{
			while (pointer != *chain_tail_point)
			{
				pointer->ready_time++;
				pointer = pointer->next;
			}pointer->ready_time++;
		}
		else if (statue == 1)//使阻塞时间--
		{
			while (pointer != *chain_tail_point && pointer!=NULL)
			{
				pointer->block_time--;
				pointer = pointer->next;
			}
			if (pointer != NULL)
			{
				pointer->block_time--;
			}

		}
		else if (statue == 2)//恢复阻塞时间清零的节点
		{
			struct PCB* temp;
			while (pointer != NULL)
			{
				if (pointer->block_time <= 0)
				{
					temp = pointer;
					pointer = pointer->next;
					re_processByPointer(temp);
				}
				else
				{
					pointer = pointer->next;
				}
			}
		}
	}

	return NULL;
}


/*



							以下为cpu代码



*/

int sys_timer = 0;//系统计时时间片

int process_timer_limit = 0;

void go_around()
{
	printf("CPU在闲逛\n");
}

void TIME_PASS()//检测阻塞时间,如果阻塞时间清零,则恢复
{
	++sys_timer;
	chain_DoForEach(&ready_listHEAD, &ready_listTAIL, 0);
	chain_DoForEach(&wait_listHEAD, &wait_listTAIL, 1);
	chain_DoForEach(&wait_listHEAD, &wait_listTAIL, 2);
	//show_process(free_listHEAD, ready_listHEAD, wait_listHEAD);
	//system("pause");
}
void CPU()
{
	while (1)
	{
		//如果没有进程,则装载进程
		int flag = check_doing();
		if (flag == 1)
		{
			printf("下一进程装载成功\n");
		}
		else if (flag == 0)
		{
			if (sys_timer == running->server_time)//如果进程执行完毕,时间片归零,将进程PCB释放
			{
				char name[20];
				strcpy_s(name, running->name);
				printf("\t%s\t进程已执行完毕\n", name);
				sys_timer = 0;
				struct PCB* temp = chain_delByName(name, &running, &running);
				chain_appendInit(temp, &free_listHEAD, &free_listTAIL);
			}

			else if (sys_timer == process_timer_limit)
			{
				char name[20];
				int block_time = int(rand() % 10);
				struct PCB* temp = NULL;
				strcpy_s(name, running->name);
				running->server_time -= process_timer_limit;
				sys_timer = 0;
				printf("时间片已耗尽,切换至下一个进程\n");
				printf("\t%s\t进程剩余服务时间为%d\t\n", name, running->server_time);
				temp = block_process(block_time);
			}
			TIME_PASS();
		}
		else if (flag == 2)
		{
			return;
		}
		else if (flag == 3)
		{
			TIME_PASS();
			sys_timer = 0;
		}



	}
}





/*




							简化操作区




*/
void CLEAN_BUFF()
{
	char ch;
	while ((ch = getchar()) != EOF && ch != '\n');
}

void CLEAR()
{
	system("cls");
}




/*





					初始化程序区



*/
void Init_PCBS()//初始化PCBS队列
{
	int i;
	for (i = 0; i < 9; ++i)
	{
		PCBS[i].state = 0;//将所有PCB置为空闲状态
		PCBS[i].server_time = 0;//将时间片大小设置为0
		memset(PCBS[i].device, 0, sizeof(PCBS[i].device));//将临界资源需求初始化
		PCBS[i].next = &PCBS[i + 1];
		PCBS[i].block_time = 0;
		PCBS[i].ready_time = 0;
	}
	PCBS[9].state = 0;
}

void Init_System()
{
	printf("请输入时间片大小\n");
	scanf_s("%d", &process_timer_limit);
	CLEAN_BUFF();
	CLEAR();
	while (1)
	{
		char command[30];
		printf("\n#user > ");
		gets_s(command);
		if (!strcmp(command, "clear") || !strcmp(command, "cls"))
		{
			CLEAR();
		}
		else if (!strcmp(command, "run"))
		{
			CPU();
		}
		else if (!strncmp(command, "load ", 5) && strlen(command)>5)
		{
			char name[20];
			int device[5];
			memset(device, 0, sizeof(device));
			int server_time = 0;
			strcpy_s(name, command + 5);
			if (name == NULL)
			{
				printf("创建进程失败\n");
				break;
			}
			printf("请输入所需的服务时间:\n");
			scanf_s("%d", &server_time);
			CLEAN_BUFF();
			printf("程序是否需要使用键盘,鼠标,打印机:\n");
			scanf_s("%d %d %d", &device[keyboard], &device[mouse], &device[printer]);
			CLEAN_BUFF();
			if (server_time != 0)
			{
				if (create_process(name, server_time) == 1)
				{
					printf("已装载进程\t%s\n", name);
				}
				else
				{
					printf("创建进程\t%s\t失败\n", name);
				}
			}
		}
		else if (!strcmp(command, "help"))
		{
			printf("啥也没有(= W =)\n");
		}
		else if (!strcmp(command, "exit"))
		{
			exit(0);
		}
		else
		{
			printf("未知命令,若想查看更多命令用法,请输入help命令\n");
		}
	}
}




int main()
{

	Init_PCBS();
	Init_System();

}

之后会继续更新其他部分

你可能感兴趣的:(课程设计,课程设计,链表,数据结构,系统架构,算法)