Operating system job 02

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.

Posted by john-formby on Tue, 16 Apr 2019 19:39:34 -0700