Experimento del sistema operativo: algoritmo de programación del procesador (lenguaje C)

Tabla de contenido

Requisitos experimentales

Código

resultado de la operación

Análisis de código


 

Requisitos experimentales

1. Establezca la cantidad de procesos en el sistema y cada proceso está representado por un bloque de control de proceso.

2. Ingrese el "número de prioridad" y el "tiempo de ejecución requerido" de cada proceso.

3. Para facilitar la programación, los procesos se conectan en una cola lista de acuerdo con el número de prioridad dado, de mayor a menor. Utilice una unidad para indicar el primer proceso de la cola.

4. La programación del procesador siempre selecciona el primer proceso de la cola para ejecutar. Adopte el algoritmo de programación round robin de intervalos de tiempo

5. Si el tiempo de ejecución requerido es cero, establezca su estado en "Fin" y salga de la cola.

6. Ejecute el programa diseñado para mostrar o imprimir el nombre del proceso seleccionado y el proceso de cambio dinámico del bloque de control de proceso.

2d4a17a8dbd041edbb18dec08012ecab.png

Código

#include <stdio.h>
#define maxPCB 1000      //最大同时处理的进程个数
void PrintPCB(int n,int i);
void Sort(int n);
int Updatequeue(int n,int now);
int N;  	//n=N,记录初始进程块的数量 
int x=0;   	//x为已结束的进程数 
//定义一个结构体数组保存各个进程的信息
struct PCB{
	int id;
	//节点携带的数据
	int priority;    //优先级
	int time;    	 //处理机所需时间
	char state[1];   //状态
	char name[2];     //进程名
}PCB[maxPCB];

//初始化
void Init(int n)      
{
	int i;
	for(i=0;i<n;i++)  
	{
		PCB[i].id=i;
		PCB[i].state[0]='R';     //程序开始运行前,默认状态都为就绪态(Ready) 
		sprintf(PCB[i].name,"P%d",i);  //默认按P0-Pn的顺序存入进程名 
		printf("P%d的优先级为:",i);
		scanf("%d",&PCB[i].priority);//输入优先级
		printf("P%d的运行时间为:",i);
		scanf("%d",&PCB[i].time);    //输入运行时间
	}
	Sort(n);
	printf("\n按优先级从大到小进入队列后...\n");
	PrintPCB(n,0);  //打印初始排序后的队列 
}

//结果打印,用于打印结果
void PrintPCB(int n,int i)
{
	int t=n;
	int p;
	int c=n;
	printf("--------------------------------------\n");
	printf("进程名   优先数   要求运行时间   状态\n");
	while(c--)										//	按顺序打印已存在队列 
	{
		printf("  %c%c       %d\t      %d       \t   %c\t\n",PCB[i].name[0],PCB[i].name[1],PCB[i].priority,PCB[i].time,PCB[i].state[0]);
		i++;
		if(i==t) i=0;//计数满,清零 
	}
	printf("--------------------------------------\n");
	for(p=0;p<x;p++)								//打印出已经退出队列的进程,方便对比 
	{
		printf("  %c%c       %d\t      %d       \t   %c\t\n",PCB[p+N].name[0],PCB[p+N].name[1],PCB[p+N].priority,PCB[p+N].time,PCB[p+N].state[0]);
	}
	printf("--------------------------------------\n");
}

//选择排序
void Sort(int n)          
{
	int i,j,maxpriority,temp1,temp2;
	for(i=0;i<n;i++)
	{
		maxpriority=PCB[i].priority;
		for(j=i;j<n;j++)
		{
			if(maxpriority<PCB[j].priority)
			{
				
				maxpriority=PCB[j].priority;
				PCB[n]=PCB[i];
				PCB[i]=PCB[j];
				PCB[j]=PCB[n];				
			}
		}
	}
}


int Start(int temp)
{
	static now=0;						//静态变量now,作为指针进行+1轮转,保存上一次运行位置 
	//int temp;
	printf("P%d进程执行中....\n结果为:\n",PCB[now].id);
	PCB[now].time--;  					//执行一次,所需时间减1 
	if(PCB[now].time<=0)	PCB[now].state[0]='E';  //进程结束,置状态位为E,退出队列 
					
	if(PCB[now].time<=0)
	{
		temp=Updatequeue(temp,now);					
		now=0;										//删除队首后,now指针不需要动 
	}else	now++;									//如果没有更新,now指针+1 
	if(now==temp)						//计满清零
	{
		now=0;
	}
	PrintPCB(temp,now); //打印新的队列状态表 
	return temp;
}

//就绪队列更新 
int Updatequeue(int n,int now)
{
	int i;
	PCB[N+x]=PCB[now];
	printf("P%d结束运行,退出就绪队列\n\n",PCB[now].id);
	for(i=now;i<n-1;i++) 
	{
		PCB[i]=PCB[i+1];
	}
	n=n-1;				
	x++;
	return n;
}

//运行状态检查 
int Runcheck(int n)    //检查剩余进程状态位是否为'E',否则返回真 
{
	int i;
	for(i=0;i<n;i++)
	{
		if(PCB[i].state[0]=='R')   
		{
			return 1;
		}
	}
	return 0;
}

//启动函数 
void Run(int n)			
{
	while(Runcheck(n))	//反复检查进程,如果全为'E',则循环结束,算法结束 
	{
		n=Start(n);		//将返回新的进程个数作为实参继续传入函数 
	}
}
int main()
{
	int n;
	printf("请输入进程个数:") ;
	scanf("%d",&n);
	N=n; 
	Init(n);  
	Run(n);
	return 0; 
}

resultado de la operación

Los resultados de ejecutar el programa son los siguientes.

b083d2c61ae9400f9e7974491b4abf08.png

 El bit de estado representa el estado del proceso, R es Listo, E es Salir

Análisis de código

Defina una matriz de estructura para almacenar datos (aquí también se puede usar una lista vinculada)

struct PCB{
	int id;
	//节点携带的数据
	int priority;    //优先级
	int time;    	 //处理机所需时间
	char state[1];   //状态
	char name[2];     //进程名
}PCB[maxPCB];

 Función de inicialización, solicita al usuario la entrada y lee la información del proceso desde el teclado.

void Init(int n)      
{
	int i;
	for(i=0;i<n;i++)  
	{
		PCB[i].id=i;
		PCB[i].state[0]='R';     //程序开始运行前,默认状态都为就绪态(Ready) 
		sprintf(PCB[i].name,"P%d",i);  //默认按P0-Pn的顺序存入进程名 
		printf("P%d的优先级为:",i);
		scanf("%d",&PCB[i].priority);//输入优先级
		printf("P%d的运行时间为:",i);
		scanf("%d",&PCB[i].time);    //输入运行时间
	}
	Sort(n);
	printf("\n按优先级从大到小进入队列后...\n");
	PrintPCB(n,0);  //打印初始排序后的队列 
}

Los resultados se imprimen. Los dos parámetros pasados ​​son el número de procesos en la cola listos y el número de procesos que han salido. Controlan el número de impresiones.

void PrintPCB(int n,int i)
{
	int t=n;
	int p;
	int c=n;
	printf("--------------------------------------\n");
	printf("进程名   优先数   要求运行时间   状态\n");
	while(c--)										//	按顺序打印已存在队列 
	{
		printf("  %c%c       %d\t      %d       \t   %c\t\n",PCB[i].name[0],PCB[i].name[1],PCB[i].priority,PCB[i].time,PCB[i].state[0]);
		i++;
		if(i==t) i=0;//计数满,清零 
	}
	printf("--------------------------------------\n");
	for(p=0;p<x;p++)								//打印出已经退出队列的进程,方便对比 
	{
		printf("  %c%c       %d\t      %d       \t   %c\t\n",PCB[p+N].name[0],PCB[p+N].name[1],PCB[p+N].priority,PCB[p+N].time,PCB[p+N].state[0]);
	}
	printf("--------------------------------------\n");
}

Ordene los procesos de entrada según la prioridad de mayor a menor. Una vez completada la clasificación, ingresan a la cola lista. Esta función solo se ejecuta una vez. Una vez que el proceso ingresa a la cola, no es necesario ordenarlo nuevamente.

//选择排序
void Sort(int n)          
{
	int i,j,maxpriority,temp1,temp2;
	for(i=0;i<n;i++)
	{
		maxpriority=PCB[i].priority;
		for(j=i;j<n;j++)
		{
			if(maxpriority<PCB[j].priority)
			{
				
				maxpriority=PCB[j].priority;
				PCB[n]=PCB[i];
				PCB[i]=PCB[j];
				PCB[j]=PCB[n];				
			}
		}
	}
}

Algoritmo central: implementación específica del algoritmo de programación de rotación de intervalos de tiempo. El puntero ahora apunta a la posición de rotación actual y se define como un tipo estático. Al regresar a la función, debe seguir inmediatamente a la posición de rotación actual (de lo contrario, la ejecución siempre comenzará desde la estructura con el subíndice 0, que obviamente no cumple los requisitos)

int Start(int temp)
{
	static now=0;						//静态变量now,作为指针进行+1轮转,保存上一次运行位置 
	//int temp;
	printf("P%d进程执行中....\n结果为:\n",PCB[now].id);
	PCB[now].time--;  					//执行一次,所需时间减1 
	if(PCB[now].time<=0)	PCB[now].state[0]='E';  //进程结束,置状态位为E,退出队列 
					
	if(PCB[now].time<=0)
	{
		temp=Updatequeue(temp,now);					
		now=0;										//删除队首后,now指针不需要动 
	}else	now++;									//如果没有更新,now指针+1 
	if(now==temp)						//计满清零
	{
		now=0;
	}
	PrintPCB(temp,now); //打印新的队列状态表 
	return temp;
}

 Se llama cuando un proceso finaliza la ejecución para actualizar la cola lista restante actual.

//就绪队列更新 
int Updatequeue(int n,int now)
{
	int i;
	PCB[N+x]=PCB[now];
	printf("P%d结束运行,退出就绪队列\n\n",PCB[now].id);
	for(i=now;i<n-1;i++) 
	{
		PCB[i]=PCB[i+1];
	}
	n=n-1;				
	x++;
	return n;
}

Verifique todos los bits de bandera, si se encuentra R, la programación no ha finalizado, devuelva 1

Si no se encuentra R en la verificación, significa que la programación ha finalizado y se devuelve 0.

//运行状态检查 
int Runcheck(int n)    //检查剩余进程状态位是否为'E',否则返回真 
{
	int i;
	for(i=0;i<n;i++)
	{
		if(PCB[i].state[0]=='R')   
		{
			return 1;
		}
	}
	return 0;
}

 Llame a la función del algoritmo y determine continuamente si el programa debe finalizar

//启动函数 
void Run(int n)			
{
	while(Runcheck(n))	//反复检查进程,如果全为'E',则循环结束,算法结束 
	{
		n=Start(n);		//将返回新的进程个数作为实参继续传入函数 
	}
}
función principal
int main()
{
	int n;
	printf("请输入进程个数:") ;
	scanf("%d",&n);
	N=n; 
	Init(n);  
	Run(n);
	return 0; 
}

Gracias por leer ~ Si tienes alguna buena sugerencia, puedes comentar o enviarme un mensaje privado ~ Si no entiendes algo, también puedes enviarme un mensaje privado ~

Si lo encuentras útil, dale me gusta y vete ~

 

Supongo que te gusta

Origin blog.csdn.net/Lic_Ac/article/details/127982323
Recomendado
Clasificación