0

I'm making a load balancer (a very simple one). It looks at how long the user has been idle, and the load on the system to determine if a process can run, and it goes through processes in a round-robin fashion.

All of the data needed to control the processes are stored in a text file. The file might look like this:

 PID=4390 IDLE=0.000000 BUSY=2.000000 USER=2.000000
 PID=4397 IDLE=3.000000 BUSY=1.500000 USER=4.000000
 PID=4405 IDLE=0.000000 BUSY=2.000000 USER=2.000000
 PID=4412 IDLE=0.000000 BUSY=2.000000 USER=2.000000
 PID=4420 IDLE=3.000000 BUSY=1.500000 USER=4.000000

This is a university assignment, however parsing the text file isn't supposed to be a big part of it, which means I can use whatever way is the quickest for me to implement.

Entries in this file will be added and removed as processes finish or are added under control.

Any ideas on how to parse this?

Thanks.

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
Blackbinary
  • 3,936
  • 18
  • 49
  • 62
  • Parsing it is easy. The hard part is going to be making sure you don't try to read it while something else is writing it. – Blrfl Mar 06 '11 at 14:27

3 Answers3

1

As far as just parsing is concerned, something like this in a loop:

int pid;
float idle, busy, user;
if(fscanf(inputStream, "PID=%d IDLE=%f BUSY=%f USER=%f", %pid, &idle, &busy, &user)!=4)
{
    /* handle the error */
}

But as @Blrfl pointed out, the big problem is to avoid mixups when your application is reading the file and the others are writing to it. To solve this problem you should use a lock or something like that; see e.g. the flock syscall.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
1

Here is a code that will parse your file, and also account for the fact that your file might be unavailable (that is, fopen might fail), or being written while you read it (that is, fscanf might fail). Note that infinite loop, which you might not want to use (that's more pseudo-code than actual code to be copy-pasted in your project, I didn't try to run it). Note also that it might be quite slow given the duration of the sleep there: you might want to use a more advanced approach, that's more sort of a hack.

int pid;
float idle, busy, user;

FILE* fid;
fpos_t pos;
int pos_init = 0;

while (1)
{
  // try to open the file
  if ((fid = fopen("myfile.txt","rw+")) == NULL)
  {
     sleep(1); // sleep for a little while, and try again
     continue; 
  }

  // reset position in file (if initialized)
  if (pos_init)
     fsetpos (pFile,&pos);

  // read as many line as you can
  while (!feof(fid))
  {
     if (fscanf(fid,"PID=%d IDLE=%f BUSY=%f USER=%f",&pid, &idle, &busy, &user))
     {
        // found a line that does match this pattern: try again later, the file might be currently written
        break;
     }

     // add here your code processing data         

     fgetpos (pFile,&pos); // remember current position
     pos_init = 1; // position has been initialized
  }

  fclose(fid);
}
Greg
  • 6,038
  • 4
  • 22
  • 37
  • You forgot all the ampersands, and all the fields (minus `pid`) are `float`s. – Matteo Italia Mar 06 '11 at 14:34
  • I'm not sure who to give the correct answer to. I'm choosing Greg because you included the loop and file opening, as a more complete answer. – Blackbinary Mar 06 '11 at 14:46
  • @Blackinary: i heavily modified my answer in order to account for the fact that the file that you are reading might be unavailable, or might be being written to while you read it. – Greg Mar 06 '11 at 14:59
  • Actually, it can't be unavailable because earlier in the program I create it if it is unavailable. And it can't be being written to as I've enclosed it in flocks. Am i missing anything? – Blackbinary Mar 06 '11 at 15:08
  • Ah. I thought that this file was written by a series of other processes, and that your program was reading it concurrently. So nevermind :P If your file is entirely under the control of your (single-threaded) program, then you do not need to lock it (if your design is correct). – Greg Mar 06 '11 at 15:09
0

Use fscanf in a loop. Here's a GNU C tutorial on using fscanf.

/* fscanf example */
#include <stdio.h>

typedef struct lbCfgData {
    int pid;
    double idle;
    double busy;
    double user;
} lbCfgData_t ;

int main ()
{
    // PID=4390 IDLE=0.000000 BUSY=2.000000 USER=2.000000
    lbCfgData_t cfgData[128];

    FILE *f;

    f = fopen ("myfile.txt","rw+");
    for (   int i = 0; 
            i != 128 // Make sure we don't overflow the array
            && fscanf(f, "PID=%u IDLE=%f BUSY=%f USER=%f", &cfgData[i].pid, 
                &cfgData[i].idle, &cfgData[i].busy, cfgData[i].user ) != EOF; 
            i++
        );

    fclose (f);
    return 0;
}
Robert S. Barnes
  • 39,711
  • 30
  • 131
  • 179