Bootstrap

基于双向循环链表的进程管理系统——C语言代码实现

#include<stdio.h>
#include <malloc.h>
#include<conio.h>
#include<stdlib.h>

typedef struct process_node
{
	int pid;
	process_node* next, * pre;
}process_node;

typedef struct management_zone
{
	process_node* head;
}management_zone;

management_zone* zone_init();
//内存管理区域初始化
process_node* process_node_init();
//进程节点创建
void process_new(management_zone* zone, int pid);
//创建新进程并加入ready区
void process_add(management_zone* zone, process_node* process_node);
//往指定区域增加进程
process_node* process_remove(process_node* p);
//删除指定节点并返回该节点地址
process_node* find_process_by_pid(management_zone* zone, int pid);
//根据pid找到指定进程并返回该节点地址
void execute_process(management_zone* ready_zone, management_zone* running_zone);
//从ready区拉去第一个进程到running区
void time_slice_cut(management_zone* ready_zone, management_zone* running_zone);
//时间片限制,暂停running区当前进程
void  process_block(management_zone* running_zone, management_zone* stopped_zone);
//由于阻塞,运行中的程序暂时拉起
void  process_unblock(management_zone* stopped_zone, management_zone* ready_zone);
//等待事件结束,重新挂起
void process_ending(management_zone* running_zone);
//结束进程

void zone_information_print(management_zone* ready_zone, management_zone* running_zone, management_zone* stopped_zone);
//打印所有区域信息
void single_zone_information_print(management_zone* zone, const char* name);
//打印单个区域信息

void controller();

int main()
{
	controller();
	return 0;
}

management_zone* zone_init()
{
	/// <summary>
	/// 进程管理区域初始化
	/// </summary>
	/// <returns></returns>
	management_zone* zone = (management_zone*)malloc(sizeof(management_zone));
	if (zone)
	{
		zone->head = process_node_init();
		return zone;
	}
	else
	{
		printf("进程管理区内存申请错误!\n");
		return NULL;
	}
}

process_node* process_node_init()
{
	/// <summary>
	/// 进程初始化
	/// </summary>
	/// <returns></returns>
	process_node* p = (process_node*)malloc(sizeof(process_node));
	if (p)
	{
		p->pid = -1;
		p->next = NULL;
		p->pre = NULL;
		return p;
	}
	else
	{
		printf("进程内存申请错误!\n");
		return NULL;
	}
}

void zone_information_print(management_zone* ready_zone, management_zone* running_zone, management_zone* stopped_zone)
{
	single_zone_information_print(ready_zone, "ready zone:");
	single_zone_information_print(running_zone, "running zone:");
	single_zone_information_print(stopped_zone, "stopped zone:");
	printf("按1新建进程 \n");
	printf("按2顺序执行进程 \n");
	printf("按3时间片限制 \n");
	printf("按4发生等待事件 \n");
	printf("按5结束等待事件 \n");
	printf("按6结束进程 \n");
	printf("按7优先指定进程 \n");
	printf("\n");
	printf("按esc退出 \n");
}

void single_zone_information_print(management_zone* zone, const char* name)
{
	printf("%s\n", name);
	//printf("head:%p\n", zone->head);
	if (zone->head->next)
		//判断管理区域是否有进程,避免操作null
	{
		process_node* p = zone->head->next;
		while (p != zone->head)
		{
			printf("%d-->", p->pid);
			p = p->next;
		}
	}
	printf("\n");
}

void process_new(management_zone* zone, int pid)
{
	process_node* p = process_node_init();
	if (p)
	{
		//修改双向循环链表链接关系
		p->pid = pid;
		process_add(zone, p);
	}
	else
	{
		printf("新建进程内存申请失败\n");
	}
}

void process_add(management_zone* zone, process_node* process_node)
{
	if (zone->head->pre)
		//判断管理区域是否有进程,避免操作null
	{
		process_node->pre = zone->head->pre;
		process_node->next = zone->head;
		zone->head->pre->next = process_node;
		zone->head->pre = process_node;
	}
	else
	{
		zone->head->next = process_node;
		zone->head->pre = process_node;
		process_node->next = zone->head;
		process_node->pre = zone->head;
	}
}

process_node* process_remove(process_node* p)
{
	if (p->pre == p->next)
		//判断p是否为区域内唯一进程
	{
		p->pre->next = NULL;
		p->next->pre = NULL;
	}
	else
	{
		p->pre->next = p->next;
		p->next->pre = p->pre;
	}
	p->pre = NULL;
	p->next = NULL;
	return p;
}

process_node* find_process_by_pid(management_zone* zone, int pid)
{
	process_node* p = zone->head->next;
	if (p)
	{
		while (p != zone->head)
		{
			if (p->pid == pid)
			{
				return p;
			}
			p = p->next;
		}
		printf("该区域不存在此进程\n");
		return NULL;
	}
	else
	{
		printf("该区域为空\n");
		return NULL;
	}
}

void execute_process(management_zone* ready_zone, management_zone* running_zone)
{
	process_node* p = ready_zone->head->next;
	if (p)
	{
		process_remove(p);
		process_add(running_zone, p);
		printf("新进程执行成功\n\n");
	}
	else
	{
		printf("ready区无进程\n\n");
	}
}

void time_slice_cut(management_zone* ready_zone, management_zone* running_zone)
{
	process_node* p = running_zone->head->next;
	if (p)
	{
		process_remove(p);
		process_add(ready_zone, p);
		printf("时间片限制成功\n");
	}
	else
	{
		printf("当前running区无进程\n");
	}
}

void process_block(management_zone* running_zone, management_zone* stopped_zone)
{
	process_node* p = running_zone->head->next;
	if (p)
	{
		process_remove(p);
		process_add(stopped_zone, p);
		printf("进程阻塞成功\n");
	}
	else
	{
		printf("running区无正在执行的进程\n");
	}
}

void process_unblock(management_zone* stopped_zone, management_zone* ready_zone)
{
	process_node* p = stopped_zone->head->next;
	if (p)
	{
		process_remove(p);
		process_add(ready_zone, p);
		printf("进程等待完成\n");
	}
	else
	{
		printf("stopped区无正在等待的进程\n");
	}
}

void process_ending(management_zone* running_zone)
{
	process_node* p = running_zone->head->next;
	if (p)
	{
		int pid = p->pid;
		process_remove(p);
		free(p);
		printf("%d进程已结束\n", pid);
	}
	else
	{
		printf("running区无进程\n");
	}
}

void controller()
{
	management_zone* ready_zone, * stopped_zone, * running_zone;
	process_node* p = NULL;
	ready_zone = zone_init();
	stopped_zone = zone_init();
	running_zone = zone_init();

	int key;
	int pid = 1;

	zone_information_print(ready_zone, running_zone, stopped_zone);
	while (1)
	{
		key = _getch();
		while (!(key == 27 || (key >= 48 && key <= 57)))
		{
			key = _getch();
		}
		printf("\n");
		if (key == 27) break;
		switch (key)
		{
		case 49:
			//1
			process_new(ready_zone, pid++);
			break;
		case 50:
			//2
			execute_process(ready_zone, running_zone);
			break;
		case 51:
			//3
			time_slice_cut(ready_zone, running_zone);
			break;
		case 52:
			//4
			process_block(running_zone, stopped_zone);
			break;
		case 53:
			//5
			process_unblock(stopped_zone, ready_zone);
			break;
		case 54:
			//6
			process_ending(running_zone);
			break;
		case 55:
			//7
			int ppid;
			process_node* pp;
			printf("请输入需要优先运行的pid(输入0退出):");
			scanf("%d", &ppid);
			while (getchar() != '\n');
			if (!ppid) break;
			while (!(pp = find_process_by_pid(ready_zone, ppid)))
			{
				printf("请输入需要优先运行的pid(输入0退出):");
				scanf("%d", &ppid);
				while (getchar() != '\n');
				if (!ppid) break;
			}
			if (!ppid) break;
			process_remove(pp);
			process_add(running_zone, pp);
			break;
		default:
			break;
		}
		system("cls");
		zone_information_print(ready_zone, running_zone, stopped_zone);
	}
}
;