Thread: crazy pipe/fork

  1. #1
    Registered User
    Join Date
    Mar 2008
    Posts
    147

    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

  2. #2
    Registered User
    Join Date
    Mar 2008
    Posts
    147
    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

  3. #3
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    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.
    Last edited by cas; 03-12-2009 at 06:32 PM. Reason: Removed accidentally duplicated code.

  4. #4
    Registered User
    Join Date
    Mar 2008
    Posts
    147
    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;
    }

  5. #5
    Registered User
    Join Date
    Mar 2008
    Posts
    147
    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

  6. #6
    Registered User
    Join Date
    Mar 2008
    Posts
    147
    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

  7. #7
    Registered User
    Join Date
    Mar 2009
    Posts
    11
    hmmmm i dont understand your results either sometimes it works andsometimes it doesnt have you tryed testing it on differnt versions of linux?

  8. #8
    Registered User
    Join Date
    Mar 2008
    Posts
    147
    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 ?

  9. #9
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. going crazy over copy
    By strij85 in forum C++ Programming
    Replies: 10
    Last Post: 07-22-2004, 11:38 PM
  2. printer gone crazy
    By DavidP in forum Tech Board
    Replies: 2
    Last Post: 03-29-2004, 01:16 AM
  3. crazy
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 23
    Last Post: 08-31-2002, 08:54 PM
  4. crazy output
    By asirep in forum C Programming
    Replies: 22
    Last Post: 04-09-2002, 11:41 AM
  5. Replies: 1
    Last Post: 02-24-2002, 06:24 PM