2016-11-03 2 views
1

Je suis en train d'écrire un algorithme de planification du premier arrivé, premier servi. Je crois que j'ai le bon algorithme et je suis en train de traiter les tâches dans le bon ordre et le bon moment pour ma liste de processus. Seul problème que j'ai est avec la façon dont il est en sortie dans mon fichier de sortie. Tous les autres noms de travaux sont en cours de sortie, à l'exception du premier travail de la liste.Chaîne aléatoire de caractères lors de la sortie dans le fichier C

Voici mon fichier d'en-tête: fcfs.h

#ifndef FUNCTION_H 
#define FUNCTION_H 

//--------------------------------------------------------------------------- 
// STRUCTURE THAT HOLDS CPU INFORMATION          | 
//-------------------------------------------------------------------------- 

// Struct that simulates the cpu running, cpu1 being the cpu currently running 
// tells what the clock pulse is, its current job, and whether or not it is 
// occupied 
struct cpu 
{ 
    int clock_pulse; 
    struct processes* job; 
    bool occupied; 
}cpu1 = {0, NULL, false}; 


//--------------------------------------------------------------------------- 
// FUNCTIONS FOR CPU              | 
//-------------------------------------------------------------------------- 

void increment_clock_pulse(); // increments clock_pulse by 1 

bool is_cpu_occupied(); // returns true if cpu is occupied, false otherwise 

void check_arrivals(); // changes cpu1 state and waiting queue 

//--------------------------------------------------------------------------- 
// STRUCTURE THAT HOLDS INFORMATION FOR PROCESS QUEUE      | 
//-------------------------------------------------------------------------- 

// Structure that holds individual nodes for each process in the waiting 
// queue. Holds process name, arrival time, service time, priority level 
struct processes 
{ 
    char name[10]; 
    int arrival_time; 
    int service_time; 
    int priority_level; 
    struct processes *next; 
}; 

struct processes *head = NULL; // instance of processes that points to beginning 

struct processes *rear = NULL; // instance of processes that points to end 

//--------------------------------------------------------------------------- 
// BASIC FUNCTIONS FOR LINKED LIST QUEUE         | 
//-------------------------------------------------------------------------- 

void enqueue(char *n, int a, int s, int p); // places process at the back of the queue 

void dequeue(); // removes the front of the queue 

void print_list(); // prints out the list of processes 

bool is_empty(); // returns true if empty, false if not 

//--------------------------------------------------------------------------- 
// FUNCTION FOR READING FILE INTO QUEUE          | 
//-------------------------------------------------------------------------- 
void fill_array(char *file); // fills in the queue from file input 

void output(); // outputs the jobs into output.txt, creates it if it doesn't exist 

#endif 

Voici mon dossier de mise en œuvre: fcfs.c

#include "stdbool.h" 
#include "string.h" 
#include "stdio.h" 
#include "stdlib.h" 
#include "fcfs.h" 

//--------------------------------------------------------------------------- 
// FUNCTIONS FOR CPU              | 
//-------------------------------------------------------------------------- 

// increments the clock pulse by one 
void increment_clock_pulse() 
{ 
    cpu1.clock_pulse++; 
} 

// returns true if cpu is occupied, false if not 
bool is_cpu_occupied() 
{ 
    return cpu1.occupied; 
} 

// checks the queue if there are jobs ready to be serviced 
void check_arrivals() 
{ 
    // if job is ready to be serviced and if there is not already a job in the CPU 
    if(head->arrival_time <= cpu1.clock_pulse && !cpu1.occupied) 
    { 
     cpu1.occupied = true; // changes the CPU to occupied 
     cpu1.job = head;  // gives the CPU the next job 
     dequeue();   // dispatches the previous job from the queue 
    } 
} 

//--------------------------------------------------------------------------- 
// BASIC FUNCTIONS FOR LINKED LIST QUEUE         | 
//-------------------------------------------------------------------------- 

// Funtcion the takes in a string and 3 integers for its input 
// and inserts the data into the queue 
void enqueue(char *n, int a, int s, int p) 
{ 
    struct processes *temp = (struct processes*)malloc(sizeof(struct processes)); 
    strcpy(temp->name, n); 
    temp->arrival_time = a; 
    temp->service_time = s; 
    temp->priority_level = p; 
    temp->next = NULL; 
    if(head == NULL && rear == NULL){ 
     head = rear = temp; 
     return; 
    } 
    rear->next = temp; 
    rear = temp; 
} 

// Function that dequeues the first item in the queue and then moves the 
// queue forward 
void dequeue() 
{ 
    struct processes* temp = head; 
    if(head == NULL) { 
     printf("Queue is Empty\n"); 
     return; 
    } 
    if(head == rear) { 
     head = rear = NULL; 
    } 
    else { 
     head = head->next; 
    } 
    free(temp); 
} 

// Function that prints out the current queue 
void print_list() 
{ 
    struct processes *ptr = head; 
    printf("\n[ "); 

    while(ptr != NULL){ 
     printf("(%s %d %d %d) ",ptr->name, ptr->arrival_time, 
       ptr->service_time, ptr->priority_level); 
     ptr = ptr->next; 
    } 

    printf(" ]"); 
} 

// Returns true if the queue is empty, false if it is not 
bool is_empty() 
{ 
    return head == NULL; 
} 

//--------------------------------------------------------------------------- 
// FUNCTION FOR READING FILE INTO QUEUE          | 
//-------------------------------------------------------------------------- 

// Function that fills in the queue, takes in an argument that is the 
// name of the file that contains the processes 
void fill_array(char *file) 
{ 
    FILE *fp; // File pointer 
    fp = fopen(file, "r"); // opens the file to read processes 

    // checks to see whether or not fopen() is successful 
    if (fp == NULL) 
    { 
     printf("Error while opening file"); 
     exit(1); 
    } 

    // reads in data until End of File 
    int a, s, p; 
    char n[10]; 
    while(feof(fp)==0) 
    { 
     fscanf(fp, "%s %d %d %d", n, &a, &s, &p); 

     enqueue(n, a, s, p); 
    } 

    fclose(fp); 
} 

void output() 
{ 
    FILE *fp; 

    fp = fopen("output.txt", "a"); 

    fprintf(fp, "%s %d %d \n", cpu1.job->name, (cpu1.clock_pulse - cpu1.job->arrival_time), cpu1.clock_pulse); 

    fclose(fp); 
} 

Et mon fichier pilote: main.c

#include "stdbool.h" 
#include "string.h" 
#include "stdio.h" 
#include "fcfs.c" 

int main() 
{ 
    char file[20]; // buffer for file name 

    printf("Please enter your file name: "); // prompts user for file name 
    scanf("%s", file); 

    fill_array(file); // fills array from file 

    // Beginning of the FCFS Algorithm 
    while(!is_empty()) 
    { 
     if(cpu1.occupied) // If CPU is busy 
     { 
      if(cpu1.job->service_time == 0) // If current job in CPU is done CPU changes to not busy 
      { 
       output();    // outputs job to file when job is finished 
       cpu1.occupied = false; 
      } 
     } 

     check_arrivals(); // checks for arrivals in the waiting queue 

     if(cpu1.occupied) // If the CPU is occupied job is not done 
     { 
      cpu1.job->service_time--; // decrement service time of current job 
     } 

     increment_clock_pulse(); // increment the clock pulse 
    } 


    return 0; 
} 

Ceci est mon fichier d'entrée: processes.txt

A0 6 15 4 
A1 9 40 6 
A2 9 12 9 
A3 12 15 4 
A4 30 11 2 
A5 45 70 1 
A6 70 23 9 
A7 75 23 5 
A8 75 18 7 
A9 90 5 6 

Et la sortie: sortie.txt

¢ 15 21 
A1 52 61 
A2 64 73 
A3 76 88 
A4 69 99 
A5 124 169 
A6 122 192 
A7 140 215 
A8 158 233 
A9 148 238 

Chaque fois que je le lance, je reçois une autre chaîne de caractères pour la premier processus qui est écrit, dans ce cas A0. Je pense que je les passe de la file d'attente à la mauvaise CPU et il me donne des ordures brouillées.

J'ai cherché partout et ne trouve pas de réponse n'importe où. S'il vous plaît aider!

Répondre

1

Il y a un gros problème ici, et compte tenu des symptômes qu'il est très probablement lié:

// checks the queue if there are jobs ready to be serviced 
void check_arrivals() 
{ 
    // if job is ready to be serviced and if there is not already a job in the CPU 
    if(head->arrival_time <= cpu1.clock_pulse && !cpu1.occupied) 
    { 
     cpu1.occupied = true; // changes the CPU to occupied 
     cpu1.job = head;  // gives the CPU the next job 
     dequeue();   // dispatches the previous job from the queue 
    } 
} 

vous stockez la valeur de head puis vous appelez dequeue() qui supprime head mémoire. cpu1.job pointe maintenant à la mémoire non allouée => comportement indéfini

Néanmoins, le programme "presque" fonctionne correctement, c'est donc juste un problème de propriété de la mémoire. Je suggère de changer votre structure de données cpu pour être en mesure de tenir la mémoire du travail comme suit (pas plus pointeur sur job):

struct cpu 
{ 
    int clock_pulse; 
    bool occupied; 
    struct processes job; 
}cpu1 = {0, false, {"",0,0,0,NULL} }; 

Ensuite, changez ce code (et tout le code où job-> est maintenant job.)

if(head->arrival_time <= cpu1.clock_pulse && !cpu1.occupied) 
    { 
     cpu1.occupied = true; // changes the CPU to occupied 
     cpu1.job = *head;  // gives the CPU the next job 
     dequeue();   // dispatches the previous job from the queue 
    } 

si head est copiée avant d'être désallouée. Vous gardez la mémoire en sécurité dans ce cas.

+0

J'ai essayé cette approche. Deux choses sont arrivées. A0 n'a pas été écrit dans le fichier, puis le programme s'est écrasé avant de terminer. Je pense que le problème est avec le dequeuing d'abord, une fois qu'il arrive au dernier travail, il essaye de ne rien déquiler? Merci pour la réponse rapide cependant, m'a donné une idée de comment je pourrais le réparer. Je rapporterai si je fais. –

+0

Je propose une autre approche. Devrait travailler, puisque le vôtre a presque travaillé. –