-
crazy pipe/fork
hi i have a problem with either my forking or pipe which i cant spot or get my head around . Right here is my fork code:
right what this is supposed to do is when I run the program "./spool 3" for instance it is meant to make 3 child processes and put them on the fifo pipe however im getting random outputs sometimes i have 1 under of the amount of processes or 1 extra ect ect. i have tried changing for for loop and still the same problem it doesnt seem to have a pattern it seems to be all over the place. Sometimes it actully works and sometimes it doesnt and gives me random
Code:
#define MAXJOBS 100 //Specify how many jobs to accept
FILE *fifo;
int main(int argc, char* argv[]){
if(argc != 2){
fprintf(stderr, "Usage: %s <# of jobs to queue>\n", argv[0]);
exit(EXIT_FAILURE);
}
int numjobs = atoi(argv[1]);//convert second argument to integer
//Make sure the # of jobs is valid
if( (numjobs > MAXJOBS) || (numjobs <= 0) ){
numjobs = MAXJOBS;
fprintf(stderr, "Invalid # of jobs, using defined MAXJOBS: %d.\n", MAXJOBS);
}
//Create FIFO file for read / write
mkfifo("pipefile", S_IRUSR | S_IWUSR);
fprintf(stderr,"Pipe created, waiting for despooler to read...\n");
fifo=fopen("pipefile", "w");
//Store parent's PID for recognition after fork
pid_t parentid = getpid();
int i;
int priority;
pid_t forkid;
for( i=0 ; i<numjobs ; i++){
priority = rand()%MAXJOBS; //Assign random priority number
forkid = fork();
if (forkid == 0)
{//This is the child process
//Write message to pipe, PID,Priority+PID,Priority...
fprintf(fifo, "%d,%d+",getpid(),priority);
fflush(fifo);
fprintf(stderr,"Job Queued. PID: %d, Priority: %d.\n", getpid(),priority);
break;
}
}
if(parentid == getpid()){ //All jobs queued, time to exit.
fprintf(fifo,"*");//This marks the end of the job list.
fprintf(stderr,"Spooler is exiting.\n");
fclose(fifo);
return 0;
}
else{ //This is the child process
while(1){}
}
}
spool.c output:
Code:
./spool 3
Pipe created, waiting for despooler to read...
Job Queued. PID: 8539, Priority: 83.
Job Queued. PID: 8541, Priority: 77.
Job Queued. PID: 8540, Priority: 86.
Spooler is exiting.
trav@travUBUNTU:~/Desktop/99$ ./spool 2
Pipe created, waiting for despooler to read...
Job Queued. PID: 8545, Priority: 83.
Spooler is exiting.
trav@travUBUNTU:~/Desktop/99$ ./spool 1
Pipe created, waiting for despooler to read...
Spooler is exiting.
Job Queued. PID: 8552, Priority: 83.
trav@travUBUNTU:~/Desktop/99$
trav@travUBUNTU:~/Desktop/99$
trav@travUBUNTU:~/Desktop/99$ ./spool 9
Pipe created, waiting for despooler to read...
^[[AJob Queued. PID: 8565, Priority: 83.
Job Queued. PID: 8566, Priority: 86.
Job Queued. PID: 8567, Priority: 77.
Job Queued. PID: 8569, Priority: 93.
Job Queued. PID: 8570, Priority: 35.
Job Queued. PID: 8568, Priority: 15.
Job Queued. PID: 8572, Priority: 92.
Job Queued. PID: 8573, Priority: 49.
Job Queued. PID: 8571, Priority: 86.
Spooler is exiting.
trav@travUBUNTU:~/Desktop/99$ ./spool 9
despool.c output:
Code:
$ ./despool 2
Trying to read from pipe...
Reading Job. PID: 8376, Priority: 83
End of File. Stopped reading.
Dequed Job. PID: 8376, Priority: 83
trav@travUBUNTU:~/Desktop/99$ ./despool 3
Trying to read from pipe...
Reading Job. PID: 8539, Priority: 83
Reading Job. PID: 8541, Priority: 77
Reading Job. PID: 8540, Priority: 86
End of File. Stopped reading.
Dequed Job. PID: 8541, Priority: 77
Dequed Job. PID: 8539, Priority: 83
Dequed Job. PID: 8540, Priority: 86
trav@travUBUNTU:~/Desktop/99$ ./despool 2
Trying to read from pipe...
Reading Job. PID: 8545, Priority: 83
End of File. Stopped reading.
Dequed Job. PID: 8545, Priority: 83
trav@travUBUNTU:~/Desktop/99$ ./despool 1
Trying to read from pipe...
End of File. Stopped reading.
trav@travUBUNTU:~/Desktop/99$ ./despool 1
Trying to read from pipe...
error opening fifo: No such file or directory
trav@travUBUNTU:~/Desktop/99$ ./despool 9
Trying to read from pipe...
error opening fifo: No such file or directory
trav@travUBUNTU:~/Desktop/99$
trav@travUBUNTU:~/Desktop/99$ ./despool 9
Trying to read from pipe...
Reading Job. PID: 8565, Priority: 83
Reading Job. PID: 8566, Priority: 86
Reading Job. PID: 8567, Priority: 77
Reading Job. PID: 8568, Priority: 15
Reading Job. PID: 8569, Priority: 93
Reading Job. PID: 8570, Priority: 35
Reading Job. PID: 8571, Priority: 86
Reading Job. PID: 8572, Priority: 92
Reading Job. PID: 8573, Priority: 49
End of File. Stopped reading.
Dequed Job. PID: 8568, Priority: 15
Dequed Job. PID: 8570, Priority: 35
Dequed Job. PID: 8573, Priority: 49
Dequed Job. PID: 8567, Priority: 77
Dequed Job. PID: 8565, Priority: 83
Dequed Job. PID: 8571, Priority: 86
Dequed Job. PID: 8566, Priority: 86
Dequed Job. PID: 8572, Priority: 92
Dequed Job. PID: 8569, Priority: 93
trav@travUBUNTU:~/Desktop/99$
trav@travUBUNTU:~/Desktop/99$
trav@travUBUNTU:~/Desktop/99$
trav@travUBUNTU:~/Desktop/99$
trav@travUBUNTU:~/Desktop/99$
you can see that sometimes it works and sometimes it doesnt when i try to make 1 or 2 process with spool i don't get 1 or 2 i get different results.
hope you can help.
thankyou
-
i have been messing around changing values and still dont get it sometimes it works and somtimes it doesnt why is this happening?
Code:
./spool 9
Pipe created, waiting for despooler to read...
Job Queued. PID: 9361, Priority: 83.
Job Queued. PID: 9363, Priority: 77.
Job Queued. PID: 9362, Priority: 86.
Job Queued. PID: 9364, Priority: 15.
Job Queued. PID: 9365, Priority: 93.
Job Queued. PID: 9366, Priority: 35.
Spooler is exiting.
Job Queued. PID: 9368, Priority: 92.
trav@travUBUNTU:~/Desktop/99$
Code:
./despool 9
Trying to read from pipe...
Reading Job. PID: 9361, Priority: 83
Reading Job. PID: 9363, Priority: 77
Reading Job. PID: 9362, Priority: 86
Reading Job. PID: 9364, Priority: 15
Reading Job. PID: 9365, Priority: 93
Reading Job. PID: 9366, Priority: 35
Reading Job. PID: 9367, Priority: 86
End of File. Stopped reading.
Dequed Job. PID: 9364, Priority: 15
Dequed Job. PID: 9366, Priority: 35
Dequed Job. PID: 9363, Priority: 77
Dequed Job. PID: 9361, Priority: 83
Dequed Job. PID: 9367, Priority: 86
Dequed Job. PID: 9362, Priority: 86
Dequed Job. PID: 9365, Priority: 93
wanted 9 got 7
-
I don't know what your despooler is doing. I guess that it stops reading when it sees an asterisk. If so, your problem is assuming that the children will all finish writing their job messages before the parent writes the asterisk. Your parent needs to wait until all children have finished notifying about their jobs before it claims that they're finished. To do this, you need to have the children communicate with the parent somehow. Presumably the children will need to do more work at some point, and so you can't _exit() and wait(). But you can use, say, a pipe (using pipe(), not a FIFO, although you *could* use a FIFO if you really wanted to).
Also, I would recommend a different way of doing your parent-child code. Instead of:
Code:
pid_t parentid = getpid();
if(fork() == 0)
{
/* Do something childish. */
}
if(parentid == getpid())
{
/* Do something parent-like. */
}
else
{
/* Do something more childish. */
}
Just do:
Code:
if(fork() == 0)
{
/* Do something childish. */
/* Do something more childish. */
_exit(0);
}
else
{
/* Do something parent-like. */
}
The "else" is actually unnecessary, although you might like it for symmetry. Of course, you'd want to check to make sure fork() doesn't return an error in real code.
-
heres my read function on the despooler.c
Code:
void read_pipe(FILE *fifo, char* nxt, char* tok){
nxt[0] = fgetc(fifo);//read one character from pipe
if(nxt[0] == '*'){//if asterix is read, enable EOF flag
fprintf(stderr, "End of File. Stopped reading.\n");
eof = 1;
}
else if(nxt[0] == ','){//comma signifies start of priority value
curr_pid = atoi(tok);
memset(tok,'\0',10);
}
else if(nxt[0] == '+'){//+ sign signifies start of new job
add_job(curr_pid,atoi(tok));
memset(tok,'\0',10);
}
else{ //all other chars are part of the current numerical value
strcat(tok, nxt);
}
return;
}
-
right im heading to bed good night all i will pick up on this 2moz thanks for help hopefully i can sort this its a pain
-
right i have still got the same problem after reading your ideas the program seems to jump out the loop then try n go back in and add more processes to the pipe but its closed
-
hmmmm i dont understand your results either sometimes it works andsometimes it doesnt have you tryed testing it on differnt versions of linux?
-
yea i have used fedora,ubuntu , ubuntu live and red hat 5 i need it running on redhat but the program is unrealiable its like a 50% chance i will get the number of process i ask it to do im stuck and have no idea how to fix ths is there anyone here who can understand why this is happening to me ?
-
You need to post your new code. It's impossible to tell what you changed, and whether you correctly interpreted the answer I gave you earlier.
It would also be a lot easier to understand what you're saying if you used more punctuation.