Operating system job 02
subject
Please write a program to simulate the execution of several processes. It is assumed that the state of a process can be divided into execution and readiness. Each process can be represented by its PCB without creating a real process.
Organizing PCBs in a linked list is divided into three queues: freeQueue: a blank PCB queue readyQueue: a ready queue
runningQueue: An execution queue
When the program starts running, the user enters the number of processes n and the time t0/t1/... that each process needs to run. /tn. The program takes out the PCB creation process from the blank PCB queue and inserts readyQueue.
The scheduling of processes is in a random way, that is, a process is randomly selected from the ready queue and put into operation (that is, the state variables in the PCB are assigned to run). Correspondingly modify the queue in which it is located, and the process in the original running state needs to be changed to the "ready" state, inserting readyQueue.
Assuming that the time slice is 2, the time needed to run a process should be reduced by 2 to 0 after each scheduling operation, which means that the process has finished executing. PCB needs to be recycled to freeQueue.
Each time a scheduling occurs, an example of information needs to be printed: Sched: P 0 (Running - > Ready), P 3 (Ready - > Running)
Running: P3 Ready: P1->P2->P0
The above information indicates that P0 is in the running state when scheduling. Select P3 to run. PCB of P0 process enters the ready queue and is at the end of the queue. Ready queues output process names in the order of queue nodes.
Sample snippet code:
#define free 0
#define ready 1
#define running 2
#define ts 2 /* time slice */ struct PCB {
int pid; /* process ID*/
int pstate; /* process status*/
char pname; / image name*/
int ptime; /* Remaining run time*/
Strct PCB pnext; / Next PCB */}
code implementation
#include<stdio.h>
#include<malloc.h>
#include <string.h>
#include<stdlib.h>
#include<time.h>
#define free 0
#define ready 1
#define running 2
#define ts 2 /* time slice */
struct PCB {
int pid; /* Process ID */
int pstate; /* Process state */
char pname[20]; /* image name */
int ptime; /* Remaining run time */
struct PCB *pnext; /* Next PCB */
};
/*Generating Random Numbers and Using them in Random Scheduling*/
int PCBchange(int isEmpty[],int run,int PCB_num){
int lrun = rand()%PCB_num;
while(run==lrun || isEmpty[lrun]<0){ //Get random scheduling target id and prevent duplication
lrun = rand()%PCB_num;
}
return lrun;
}
/*Find the scheduling target in the ready queue and complete the handover*/
struct PCB * findAndSwitch(int Id,struct PCB * tp,struct PCB * sp){
struct PCB * getP;
struct PCB * temp;
getP = tp; //Find the location of the scheduling process
while(getP->pnext!=NULL&&getP->pnext->pid != Id){
getP = getP->pnext;
}
/*Ready queue and process switching of running queue*/
temp = getP->pnext;
if(temp->pnext!=NULL){
getP->pnext = temp->pnext; //readyQueue list operation
}else{
getP->pnext = NULL;
}
getP = sp->pnext;
sp->pnext = temp; //Connect to the running list
temp->pnext = NULL; //Zero Follow-up Bit
return getP;
}
/*Output readyQueue*/
void outputReady(struct PCB* tp){
struct PCB* getP;
printf("Ready:");
if(tp->pnext!= NULL){
getP = tp->pnext;
printf("%s",getP->pname); //Output the first element
getP = getP->pnext;
while(getP!=NULL){ //Loop out subsequent elements
printf("->%s",getP->pname);
getP = getP->pnext;
}
printf("\n");
}else
printf("NULL\n");
}
int main()
{
struct PCB * freeQueue = (struct PCB*)malloc(sizeof(struct PCB));
struct PCB * readyQueue = (struct PCB*)malloc(sizeof(struct PCB));
struct PCB * runningQueue = (struct PCB*)malloc(sizeof(struct PCB));
struct PCB * temp; //Auxiliary Operating Pointer
struct PCB * getP; //Ditto
int PCB_num; //Number of stored processes
char str[10]; //Initialize process name s
int isEmpty[50]={0}; //An array that records whether each process has completed execution
int i=0; //Auxiliary parameter
int run=-1; //Store random scheduling target id
int counter = 0; //Record the number of completed processes
int isComplete=1; //Mark bits for the continuation of the main loop
srand((unsigned) time(NULL)); //Generating seeds for random scheduling
/*Initialize POB*/
runningQueue->pnext = NULL;
printf("Please enter the number of processes:");
scanf("%d",&PCB_num);
printf("Please enter the running time of each process in turn:");
getP = freeQueue;
for(i;i<PCB_num;i ){
temp = (struct PCB*)malloc(sizeof(struct PCB)); //Request dynamic storage space
temp->pid = i; //Record id
temp->pstate = 0; //Initialization state
sprintf(str, "%d" , i); //name operation
memset(temp->pname, 0, 20); //Initialization string
temp->pname[0] = 'P';
strcat(temp->pname, str);
scanf("%d",&(temp->ptime)); //Input process run time
temp->pnext = NULL; //Initialize the pnext pointer
getP->pnext = temp; //Linked list
getP = getP->pnext;
isEmpty[i] = i; //Initialize Record Array
}
/*Conversion to ready queue*/
readyQueue->pnext = freeQueue->pnext; //Enter the Ready Queue
freeQueue->pnext = NULL;
/*Running and Random Scheduling*/
while(isComplete){
run = PCBchange(isEmpty, run, PCB_num); //Get random values
if(runningQueue->pnext==NULL){
/*First run*/
getP = findAndSwitch(run,readyQueue,runningQueue); //Locate target process and complete handover
/*output*/
printf("Sched:%s(Ready->Running)\n",runningQueue->pnext->pname);
printf("Running:%s\n",runningQueue->pnext->pname);
outputReady(readyQueue);
}
/*Determine whether the scheduling is self?*/
// else if(run==runningQueue->pnext->pid){
// printf("Sched:%s(Running->Runing)\n",runningQueue->pnext->pname);
// printf("Running:%s\n",runningQueue->pnext->pname);
// outputReady(readyQueue);
// }
/*Follow up operation*/
else{
getP = findAndSwitch(run, readyQueue, runningQueue); //Locate target process and complete handover
temp = readyQueue; //Connect to the end of the readyQueue list
while(temp->pnext!=NULL)
temp = temp->pnext;
temp->pnext = getP; //Put the process entering the ready queue at the end of the queue
/*output*/
printf("Sche:%s(Running->Ready),%s(ready->Running)\n",
getP->pname,runningQueue->pnext->pname);
printf("Running:%s\n", runningQueue->pnext->pname);
outputReady(readyQueue);
}
runningQueue->pnext->ptime -= 2; //Process Time-2
/*Transfer the completed process in the ready queue to the empty queue*/
for(i=0;i<PCB_num; i){
if(isEmpty[i] == -1)
{
isEmpty[i] = -2;
temp = readyQueue;
while(temp->pnext->pid != i)
temp = temp->pnext;
if(temp->pnext!=NULL){
getP = temp->pnext;
temp->pnext = getP->pnext;
}else{
getP = temp->pnext;
temp->pnext = NULL;
}
getP->pnext = freeQueue->pnext; //free linked list connection
freeQueue ->pnext = getP;
printf("Sche:%s(Ready->free)\n",getP->pname);
counter ; //Increase the number of completed processes by one
}
}
if(runningQueue->pnext->ptime<=0){ //Determine whether the running process is finished or not
isEmpty[run] = -1;
}
if(counter == PCB_num-1){ //Determine whether all processes are running
printf("Sche:%s(Ready->free)\n",runningQueue->pnext->pname);
isComplete = 0;
}
}
return 0;
}
Operation result
Summary
In this assignment, I found many shortcomings, such as the problem of null pointer often encountered in the operation of linked list, pointer operation on behalf of myself is still not very clinker, at the same time, I made the error of writing code by hand, which led to the code duplication of many linked list operations in the later stage, so that it was difficult to debug in the later stage, which led me to almost rewrite the linked list into the function, but even now the code logic. It's not very clear. Next time, we must conceive before we start.