Симулятор планирования Round Robin C

Я делаю симулятор для алгоритма планирования Round Robin на C. Прямо сейчас я сделал так, чтобы квант времени был равен 2. Таким образом, каждые 2 секунды он берет «процесс» из начала списка, уменьшает оставшееся время на 2, а затем вставляет его в конец списка и берет следующий. Кроме того, каждую секунду это увеличивает время ожидания других на 1. Однако, когда я пытаюсь удалить процесс из начала списка (чтобы я мог поместить его в конец списка) в функции round_Robin(), он удаляет его. Но он не добавляет его в конец связанного списка. Что я делаю неправильно? Спасибо! Я использую аргументы командной строки так:

./a.out input.dat text.txt 5 0.4

А вот мой input.dat:

1 0 10 50

2 2 0 40

3 3 20 50

4 4 7 35

5 5 10 50

6 6 0 40

7 7 20 50

8 9 7 35

9 10 10 50

10 12 0 40

И вот мой код:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define n 10
char *cRR;//get the argument for RR time
char *calpha;//get the argument for alpha 
int full[40];
int arraylength;
int RR;//to hold RR time as an int
int i=0;//used to count amount of numbers in test file
double alpha;//hold alpha time as a double
int at[n];

int global_timer=-1;


typedef int LL_pid; // the pid of the PCB
typedef int LL_AT;//the arrival time of the pcb
typedef int LL_priority;//the priority of that PCB
typedef int LL_BT;//the Burst time of that PCB
typedef int LL_remainingtime;
typedef int LL_wT;
typedef struct LL PCB; //the PCB
struct LL //linked list structure(pcb)
{
    LL_pid pid;
    LL_AT AT;
    LL_priority priority;
    LL_BT BT;
    LL_remainingtime RT;
    LL_wT wT;
    PCB *next;//points to next pcb in linked list
};
struct job//used for job queue
{
    int pid2;
    int AT2;
    int priority2;
    int BT2;
};
int LL_length(PCB *pcb_head); //linked list length
void LL_add(PCB **pcb_head,LL_pid ppid, LL_AT AAT, LL_priority ppriority, LL_BT BBT, LL_remainingtime RRT,LL_wT wTT); //adds PCB to front of list
void LL_pop(PCB **pcb_head); //removes the head from the list & returns its value
void LL_print(PCB **pcb_head); //prints all the processes
void LL_clear(PCB **pcb_head); //deletes all the processes from queue
void LL_append(PCB **pcb_head,LL_pid ppid, LL_AT AAT, LL_priority ppriority, LL_BT BBT,LL_remainingtime RRT,LL_wT wTT); //adds a process to the end of the list
int LL_elem(PCB **pcb_head, LL_pid d); //checks for the pcb via pid
void add_jobs(int jobss[]); 
struct job jobs[n];//contains all the jobs an array

void counter(PCB **pcb_head);
void round_Robin(PCB **pcb_head);


int main ( int argc, char *argv[] )
{
PCB *pcb_head=NULL;

//*****START COMMAND LINE ARGS
if ( argc != 5 )//if they incorrectly inputed arguments
    {
        /* We print argv[0] assuming it is the program name */
        printf( "usage: %s filename, output file name, RR quantum as a int, Alpha value as a float", argv[0] );
    }
    else
    {
        cRR=argv[3];//get arg for RR time
        calpha=argv[4];//get arg for alpha
        alpha=atof(calpha);//convert alpha to float
        RR=atoi(cRR);//convert RR to int


        // We assume argv[1] is a filename to open
        FILE *file = fopen( argv[1], "r" );//open file which is 2nd arg
        // fopen returns 0, the NULL pointer, on failure 
        if ( file == 0 )
        {
            printf( "Could not open file\n" );
} else
        {
        int y=0;//used for while loop below

        while  ( fscanf(file,"%d",&y)!=EOF )//scan file and find all the numbers
            {
              full[i]=y;//insert the numbers into an array
                i++;
            }
            fclose( file );//done using the file
        }
/*TEST PRINTING EVERYTHING IN FILE
int testprint=0;
for(testprint=0;testprint<i;testprint++){printf("%d\n",full[testprint]);}
printf("\nend of array check");*/
//write to file
   FILE *fp;

   fp = fopen(argv[2], "w+");
   fprintf(fp, "This is testing for fprintf...\n");

   fclose(fp);

    }
/////////////////END OF COMMAND ARGUMENT THINGS


add_jobs(full);//adds all inputs from file to the array "jobs"
counter(&pcb_head);
round_Robin(&pcb_head);




 /*
    //example usage:
    LL_add(&pcb_head, 7,7,7,7,10); //push value 7 onto stack
    printf("%d\n", pcb_head -> pid); //show stack head value
    LL_add(&pcb_head, 21,21,21,21,31); //push value 21 onto stack
    LL_print(&pcb_head); //print the stack
    if(LL_elem(&pcb_head, 7)) puts("found 7"); //does 7 belong to the stack?
    LL_append(&pcb_head, 0,0,0,0,50); //append 0 to the end of the stack
    LL_print(&pcb_head); //print the stack
    LL_pop(&pcb_head); //pop the stack's head
    LL_print(&pcb_head); //print the stack
    LL_clear(&pcb_head); //clear the stack
    LL_print(&pcb_head); //print the stack
  */
    getchar();
    return 0;
}

int LL_length(PCB *pcb_head)
{
    PCB *curr = pcb_head;//set a temp value to the head
    int len = 0;

    while(curr)
    {
        ++len;//increase length variable
        curr = curr -> next;//go to next and keep looping to get whole length
    }
    return len;
}

void LL_add(PCB **pcb_head,LL_pid ppid, LL_AT AAT, LL_priority ppriority, LL_BT BBT, LL_remainingtime RRT, LL_wT wTT)
{
    PCB *pcb_new = malloc(sizeof(PCB));//allocate memory for another structure (PCB)

    pcb_new -> pid = ppid;//create a pcb with pid inserted
    pcb_new -> AT = AAT;
    pcb_new -> priority = ppriority;
    pcb_new -> BT = BBT;
    pcb_new -> RT = RRT;
    pcb_new -> wT = wTT;
    pcb_new -> next = *pcb_head;//set its next to the head(inserting in front of list)
    *pcb_head = pcb_new;//set the pointer of head to it since it is in front of list now
}

void LL_pop(PCB **pcb_head)
{
    PCB *pcb_temp = *pcb_head; 

    printf("\nProcess %d is terminating\n", pcb_temp->pid);
    *pcb_head = pcb_temp -> next;
    free(pcb_temp);
}





void LL_print(PCB **pcb_head)
{
    PCB *pcb_temp = *pcb_head;

    if(!pcb_temp)
        puts("the list is empty");
    else
    {
      // while(pcb_temp)
       //{
            printf("Process %d has terminated...", pcb_temp -> pid);// print all the pids
       // printf("%d ", pcb_temp -> AT);
       // printf("%d ", pcb_temp -> priority);
       // printf("%d ", pcb_temp -> BT);
           //pcb_temp = pcb_temp -> next;//loop to next pcb*/
        //}
        putchar('\n');
    }
}

void LL_clear(PCB **pcb_head)
{
    while(*pcb_head)//this will get every pcb as pop below sets head value to next after deleting it
        LL_pop(pcb_head);
}


void LL_append(PCB **pcb_head,LL_pid ppid, LL_AT AAT, LL_priority ppriority, LL_BT BBT, LL_remainingtime RRT,LL_wT wTT)
{
    PCB *pcb_temp = *pcb_head;//get head value

    if(!pcb_temp)//if nothing in head value just add the pcb as list is empty
        LL_add(pcb_head, ppid, AAT, ppriority, BBT, RRT, wTT);
    else
    {
        while(pcb_temp -> next)//get the last pcb
            pcb_temp = pcb_temp -> next;

        LL_add(&(pcb_temp -> next), ppid, AAT, ppriority, BBT, RRT, wTT);//add it onto the last
    }
}

void add_jobs(int jobss[]){
int i = 0;
int i2 = 1;
int i3 = 2;
int i4 = 3;
int x =0;
int x2=0;
int x3=0;
int x4=0;
    while(x<10){
    jobs[x].pid2=jobss[i];
    x++;    
    i+=4;
    }

    while(x2<10){
    jobs[x2].AT2=jobss[i2];
    i2+=4;
    x2++;
    }


        while(x3<10){
        jobs[x3].priority2=jobss[i3];
        i3+=4;
        x3++;
        }

        while(x4<10){
        jobs[x4].BT2=jobss[i4];
        i4+=4;
        x4++;
        }
       arraylength=x4;

}



//NEED TO CHANGE 2 TO THE REAL ROUND BOBIN QUANTUM, NEED TO ADD IF RT IS LESS THEN QUANTUM, THEN PRINT FOR RT
void round_Robin(PCB **pcb_head){
PCB *pcb_temp = *pcb_head;
PCB *next = (*pcb_head)->next;//get the next value since it will be the next head
int x;
//store all the heads values
int storepid = pcb_temp->pid;
int storeat = pcb_temp->AT;
int storepriority=pcb_temp->priority;
int storebt=pcb_temp->BT;
int storert=pcb_temp->RT;
int storewt=pcb_temp->wT;


for (x=0;x<100;x++){
    if(*pcb_head){
        int h=0;
            for(h=0;h<2;h++){//2 is represented as the time quantum right now
            printf("\nProcess %d is running", (*pcb_head)->pid);
            counter(pcb_head);//even tho this increases wt we already stored original wt in storewt

            }
        LL_pop(pcb_head);//get rid of it from head
        storert-=2;//its remaining time decreases
        LL_append(&next,storepid,storeat,storepriority,storebt,storert,storewt);//append it to the list

        }
        else{
    printf("....");
    counter(pcb_head);}//run counter and see if any new processes

}



}

void counter(PCB **pcb_head){
int locator;
PCB *pcb_temp = *pcb_head;
global_timer++;//increase the time
printf("\nTIME %d:", global_timer);
        for(locator=0;locator<10;locator++){
            if (jobs[locator].AT2==global_timer){//see if any processes are ready to enter the ready queue linked list
                LL_append(pcb_head,jobs[locator].pid2,jobs[locator].AT2,jobs[locator].priority2,jobs[locator].BT2,jobs[locator].BT2,0); }           
            }
while(pcb_temp){
pcb_temp-> wT +=1;//increase everyones waiting time in the linked list ready queue
pcb_temp = pcb_temp->next;
}



}


int LL_elem(PCB **pcb_head, LL_pid x)
{
    PCB *pcb_temp = *pcb_head;//get head

    while(pcb_temp)
    {
        if(pcb_temp -> pid == x) //set for numbers, modifiable
            return 1;
        else
            pcb_temp = pcb_temp -> next;
    }
    return 0;
}

РЕДАКТИРОВАТЬ :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define n 10
char *cRR;//get the argument for RR time
char *calpha;//get the argument for alpha 
int full[40];
int arraylength;
int RR;//to hold RR time as an int
int i=0;//used to count amount of numbers in test file
double alpha;//hold alpha time as a double
int at[n];

int global_timer=-1;


typedef int LL_pid; // the pid of the PCB
typedef int LL_AT;//the arrival time of the pcb
typedef int LL_priority;//the priority of that PCB
typedef int LL_BT;//the Burst time of that PCB
typedef int LL_remainingtime;
typedef int LL_wT;
typedef struct LL PCB; //the PCB
struct LL //linked list structure(pcb)
{
    LL_pid pid;
    LL_AT AT;
    LL_priority priority;
    LL_BT BT;
    LL_remainingtime RT;
    LL_wT wT;
    PCB *next;//points to next pcb in linked list
};
struct job//used for job queue
{
    int pid2;
    int AT2;
    int priority2;
    int BT2;
};
int LL_length(PCB *pcb_head); //linked list length
void LL_add(PCB **pcb_head,LL_pid ppid, LL_AT AAT, LL_priority ppriority, LL_BT BBT, LL_remainingtime RRT,LL_wT wTT); //adds PCB to front of list
void LL_pop(PCB **pcb_head); //removes the head from the list & returns its value
void LL_print(PCB **pcb_head); //prints all the processes
void LL_clear(PCB **pcb_head); //deletes all the processes from queue
void LL_append(PCB **pcb_head,LL_pid ppid, LL_AT AAT, LL_priority ppriority, LL_BT BBT,LL_remainingtime RRT,LL_wT wTT); //adds a process to the end of the list
int LL_elem(PCB **pcb_head, LL_pid d); //checks for the pcb via pid
void add_jobs(int jobss[]); 
struct job jobs[n];//contains all the jobs an array

void counter(PCB **pcb_head);
void round_Robin(PCB **pcb_head);


int main ( int argc, char *argv[] )
{
PCB *pcb_head=NULL;

//*****START COMMAND LINE ARGS
if ( argc != 5 )//if they incorrectly inputed arguments
    {
        /* We print argv[0] assuming it is the program name */
        printf( "usage: %s filename, output file name, RR quantum as a int, Alpha value as a float", argv[0] );
    }
    else
    {
        cRR=argv[3];//get arg for RR time
        calpha=argv[4];//get arg for alpha
        alpha=atof(calpha);//convert alpha to float
        RR=atoi(cRR);//convert RR to int


        // We assume argv[1] is a filename to open
        FILE *file = fopen( argv[1], "r" );//open file which is 2nd arg
        // fopen returns 0, the NULL pointer, on failure 
        if ( file == 0 )
        {
            printf( "Could not open file\n" );
} else
        {
        int y=0;//used for while loop below

        while  ( fscanf(file,"%d",&y)!=EOF )//scan file and find all the numbers
            {
              full[i]=y;//insert the numbers into an array
                i++;
            }
            fclose( file );//done using the file
        }
/*TEST PRINTING EVERYTHING IN FILE
int testprint=0;
for(testprint=0;testprint<i;testprint++){printf("%d\n",full[testprint]);}
printf("\nend of array check");*/
//write to file
   FILE *fp;

   fp = fopen(argv[2], "w+");
   fprintf(fp, "This is testing for fprintf...\n");

   fclose(fp);

    }
/////////////////END OF COMMAND ARGUMENT THINGS


add_jobs(full);//adds all inputs from file to the array "jobs"
counter(&pcb_head);
round_Robin(&pcb_head);




 /*
    //example usage:
    LL_add(&pcb_head, 7,7,7,7,10); //push value 7 onto stack
    printf("%d\n", pcb_head -> pid); //show stack head value
    LL_add(&pcb_head, 21,21,21,21,31); //push value 21 onto stack
    LL_print(&pcb_head); //print the stack
    if(LL_elem(&pcb_head, 7)) puts("found 7"); //does 7 belong to the stack?
    LL_append(&pcb_head, 0,0,0,0,50); //append 0 to the end of the stack
    LL_print(&pcb_head); //print the stack
    LL_pop(&pcb_head); //pop the stack's head
    LL_print(&pcb_head); //print the stack
    LL_clear(&pcb_head); //clear the stack
    LL_print(&pcb_head); //print the stack
  */
    getchar();
    return 0;
}

int LL_length(PCB *pcb_head)
{
    PCB *curr = pcb_head;//set a temp value to the head
    int len = 0;

    while(curr)
    {
        ++len;//increase length variable
        curr = curr -> next;//go to next and keep looping to get whole length
    }
    return len;
}

void LL_add(PCB **pcb_head,LL_pid ppid, LL_AT AAT, LL_priority ppriority, LL_BT BBT, LL_remainingtime RRT, LL_wT wTT)
{
    PCB *pcb_new = malloc(sizeof(PCB));//allocate memory for another structure (PCB)

    pcb_new -> pid = ppid;//create a pcb with pid inserted
    pcb_new -> AT = AAT;
    pcb_new -> priority = ppriority;
    pcb_new -> BT = BBT;
    pcb_new -> RT = RRT;
    pcb_new -> wT = wTT;
    pcb_new -> next = NULL;//set its next to the head(inserting in front of list)
    *pcb_head = pcb_new;//set the pointer of head to it since it is in front of list now
}

void LL_pop(PCB **pcb_head)
{
    PCB *pcb_temp = *pcb_head; 

    printf("\nProcess %d is terminating\n", pcb_temp->pid);
    *pcb_head = pcb_temp -> next;
    free(pcb_temp);
}





void LL_print(PCB **pcb_head)
{
    PCB *pcb_temp = *pcb_head;

    if(!pcb_temp)
        puts("the list is empty");
    else
    {
      // while(pcb_temp)
       //{
            printf("Process %d has terminated...", pcb_temp -> pid);// print all the pids
       // printf("%d ", pcb_temp -> AT);
       // printf("%d ", pcb_temp -> priority);
       // printf("%d ", pcb_temp -> BT);
           //pcb_temp = pcb_temp -> next;//loop to next pcb*/
        //}
        putchar('\n');
    }
}

void LL_clear(PCB **pcb_head)
{
    while(*pcb_head)//this will get every pcb as pop below sets head value to next after deleting it
        LL_pop(pcb_head);
}


void LL_append(PCB **pcb_head,LL_pid ppid, LL_AT AAT, LL_priority ppriority, LL_BT BBT, LL_remainingtime RRT,LL_wT wTT)
{
    PCB *pcb_temp = *pcb_head;//get head value

    if(!pcb_temp)//if nothing in head value just add the pcb as list is empty
        LL_add(pcb_head, ppid, AAT, ppriority, BBT, RRT, wTT);
    else
    {
        while(pcb_temp -> next)//get the last pcb
            pcb_temp = pcb_temp -> next;

        LL_add(&(pcb_temp -> next), ppid, AAT, ppriority, BBT, RRT, wTT);//add it onto the last
    }
}

void add_jobs(int jobss[]){
int i = 0;
int i2 = 1;
int i3 = 2;
int i4 = 3;
int x =0;
int x2=0;
int x3=0;
int x4=0;
    while(x<10){
    jobs[x].pid2=jobss[i];
    x++;    
    i+=4;
    }

    while(x2<10){
    jobs[x2].AT2=jobss[i2];
    i2+=4;
    x2++;
    }


        while(x3<10){
        jobs[x3].priority2=jobss[i3];
        i3+=4;
        x3++;
        }

        while(x4<10){
        jobs[x4].BT2=jobss[i4];
        i4+=4;
        x4++;
        }
       arraylength=x4;

}



//NEED TO CHANGE 2 TO THE REAL ROUND BOBIN QUANTUM, NEED TO ADD IF RT IS LESS THEN QUANTUM, THEN PRINT FOR RT
void round_Robin(PCB **pcb_head){
int x;
for (x=0;x<250;x++){
PCB *pcb_temp = *pcb_head;
PCB *next = (*pcb_head)->next;//get the next value since it will be the next head
int storepid = pcb_temp->pid;
int storeat = pcb_temp->AT;
int storepriority=pcb_temp->priority;
int storebt=pcb_temp->BT;
int storert=pcb_temp->RT;
int storewt=pcb_temp->wT;
    if(*pcb_head){//if there is something in the list
        int h=0;
            if(storert>=2){//if the remaining time is greater than the quantum
                for(h=0;h<2;h++){//2 is represented as the time quantum right now
                    printf("\nProcess %d is running", (*pcb_head)->pid);
                    counter(pcb_head);//even tho this increases wt we already stored original wt in storewt
                    //print it for the quantum
                }
                LL_pop(pcb_head);//get rid of it from head
                storert-=2;//its remaining time decreases by the quantum
                if(storert>0){//if it still has remaining time append it
                    LL_append(&next,storepid,storeat,storepriority,storebt,storert,storewt);}//append it to the list}
                else{printf("Process has finished");}//if it doesnt type it finished
            }
            else{//if the remaining time is less then the quantum
                for(h=0;h<storert;h++){//do it for how much is remaining
                    printf("\nProcess %d is running", (*pcb_head)->pid);
                    counter(pcb_head);
                }   
            LL_pop(pcb_head);//get rid of it from head because it finished
            printf("Process has finished");     
            }
        }
    else{
    printf("....");
    counter(pcb_head);}//run counter and see if any new processes

}



}

void counter(PCB **pcb_head){
int locator;
PCB *pcb_temp = *pcb_head;
global_timer++;//increase the time
printf("\nTIME %d:", global_timer);
        for(locator=0;locator<10;locator++){
            if (jobs[locator].AT2==global_timer){//see if any processes are ready to enter the ready queue linked list
                LL_append(pcb_head,jobs[locator].pid2,jobs[locator].AT2,jobs[locator].priority2,jobs[locator].BT2,jobs[locator].BT2,0); }           
            }
while(pcb_temp){
pcb_temp-> wT +=1;//increase everyones waiting time in the linked list ready queue
pcb_temp = pcb_temp->next;
}



}


int LL_elem(PCB **pcb_head, LL_pid x)
{
    PCB *pcb_temp = *pcb_head;//get head

    while(pcb_temp)
    {
        if(pcb_temp -> pid == x) //set for numbers, modifiable
            return 1;
        else
            pcb_temp = pcb_temp -> next;
    }
    return 0;
}

person Community    schedule 26.04.2015    source источник
comment
Если реализация связанного списка не требуется, имеет смысл использовать тип GList из библиотеки GObject для обработки всех задач списка, освобождая вас для написания вашего планировщика.   -  person phil    schedule 26.04.2015


Ответы (1)


Этот код:

PCB *pcb_temp = *pcb_head;
PCB *next = (*pcb_head)->next;//get the next value since it will be the next head
//store all the heads values
int storepid = pcb_temp->pid;
int storeat = pcb_temp->AT;
int storepriority=pcb_temp->priority;
int storebt=pcb_temp->BT;
int storert=pcb_temp->RT;
int storewt=pcb_temp->wT;

необходимо выполнять в каждом цикле, а не только один раз перед циклом. В противном случае вы будете продолжать добавлять один и тот же элемент в конец вместо текущего элемента заголовка.

Кроме того, LL_add() нельзя использовать для добавления к списку, потому что всегда предполагается, что он добавляется к заголовку:

pcb_new -> next = *pcb_head;
*pcb_head = pcb_new;

Если вы добавляете к хвосту, вам нужен код, который выглядит так:

pcb_new -> next = NULL;
*tail_ptr = pcb_new;

Редактировать:

Кажется, что LL_add() всегда используется только для добавления к хвосту, а не к голове. В этом случае просто измените эту строку:

pcb_new -> next = *pcb_head;

к этому:

pcb_new -> next = NULL;

Однако, если вы сделаете это изменение, не пытайтесь вставить в головку, используя эту модифицированную версию, потому что это не сработает.

person JS1    schedule 26.04.2015
comment
Да, вы заканчиваете тем, что последние два элемента указывают друг на друга, создавая цикл в списке. - person JS1; 26.04.2015
comment
О, вы можете уточнить, какая часть делает это? Извиняюсь - person ; 26.04.2015
comment
Это уже есть в моем ответе. Просто подумайте об этом так: новый узел должен быть помещен в конец, а его следующий указатель должен указывать на NULL, верно? Что ж, его следующий указатель не равен NULL. Посмотрите на LL_add, чтобы понять, почему. - person JS1; 26.04.2015
comment
А ладно спасибо! Я исправил, но почему-то 3 работает раньше 7, а там ошибка сегментации - person ; 26.04.2015
comment
К сожалению, пора отлаживать! Привыкайте к отладке, это, наверное, самая важная часть программирования. - person JS1; 26.04.2015
comment
разобрался с ошибкой сегментации, просто не могу правильно добавить - person ; 26.04.2015