2016-11-03 72 views
1

我正在寫一個先到先得的調度算法。我相信我有正確的算法,並按正確的順序和時間處理作業列表。我唯一的問題是如何輸出到我的輸出文件。除列表中的第一項工作外,其他任何工作名稱均正確輸出。輸出到C中的文件時出現隨機字符串

這裏是我的頭文件: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 

這是我實現文件: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); 
} 

我的驅動程序文件: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; 
} 

這是我的輸入文件: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 

和輸出:output.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 

每次我運行它,我得到的字符不同的字符串爲第一個寫入的進程,在這種情況下是A0。

我的想法是,我把他們從隊列傳給CPU,錯誤的是它讓我亂七八糟的垃圾。

我已經遍地搜索,無法在任何地方找到答案。請幫忙!

回答

1

這裏有一個很大的問題,並給出了症狀,它很可能是相關的:

// 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 
    } 
} 

您存儲的head值,然後調用dequeue()其刪除head內存。 cpu1.job現在指向未分配的內存=>未定義的行爲

儘管如此,程序「幾乎」運行良好,所以這只是內存所有權問題。 我建議改變你的cpu數據結構能夠如下(上job沒有更多的指針)擔任這個職務的記憶:

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

然後更改此代碼(和所有的代碼,其中job->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 
    } 

所以head被釋放之前被複制。在這種情況下,保持記憶安全。

+0

試過這種方法。發生了兩件事。 A0沒有寫入文件,然後程序崩潰之前完成。我認爲問題在於首先將它出隊,一旦它到達最後一個工作,它就不會將任何隊列出隊?感謝您的快速反應,給了我一個如何解決它的想法。如果我這樣做,我會報告。 –

+0

我提出另一種方法。應該工作,因爲你的工作幾乎已經完成。 –