Thread: Flow of Control with fork() 6 times.

  1. #1
    Registered User
    Join Date
    Nov 2010
    Posts
    11

    Flow of Control with fork() 6 times.

    Hello, I am working on the bounded buffer consumer producer problem. I am using message queues. But i think the logic to code the children is incorrect. It does not code into cases 3-5, and I know I was able to create 6 children and exit successfully before my "real" code was inserted in each case. Here is my code and any help is greatly appreciated.

    Code:
    #include <sys/msg.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <errno.h>
    #include <signal.h>
    #include <unistd.h>
    
    int main(void){
      
      key_t key;
      int mid;
      const int DUMMYMSG = 1;
      const int VALIDMSG = 2;
      int n = 6; // number of processes
      int i, j;
      pid_t pids[6];
      key = ftok(".", 'A');
      
      // Create Message Queue
      mid = msgget(key,IPC_CREAT | 0660);
      if(mid ==-1){
        perror("Error with msgget\n");
        exit(1);
      }
      // Create msgbuf struct to send/recieve messages
      struct msgbuf{
    	long int mtype;
    	char mtext[256];
      };
      struct msgbuf message;
    
      // Create 6 process using fork()
      for(i=0; i<n; i++){
        if((pids[i] = fork()) < 0){
          perror("Error with fork\n");
          exit(1);
        }
        else if(pids[i] == 0){
          switch(i){ 
          // case 0-2 will be producers; case 3-5 will be consumers
            case 0:
     	  message.mtype = DUMMYMSG;
              strcpy(message.mtext,"Dummy Message1");
             
              for(j=0; j<20; j++){
                if(msgsnd(mid, (struct msgbuf *) &message, strlen(message.mtext)+1, 0) == -1){
                perror("Error in Main:msgsnd switch:0A\n");
                exit(1);
                }
                printf("Consumer1 Sending dummy messages...\n");
                usleep(250); // 1/4 of a second
              } // for loop 20 times
    
    	  message.mtype = VALIDMSG;
    	  strcpy(message.mtext,"Valid Message1");
    
              for(j=0; j<60; j++){
                if(msgrcv(mid, &message, sizeof(message.mtext)+1, DUMMYMSG, 0) >= 0){
                  printf("Producer1 Receiving...\n");
                  usleep(250);
                  if(msgsnd(mid, (struct msgbuf*) &message, strlen(message.mtext)+1, 0) == -1){
                    perror("Error in Main:msgsnd switch:0B\n");
                    exit(1);
                  } 
    	      printf("Producer1 Sending...\n");
                  usleep(250);
                }
                else{
    	      perror("Error in Main:msgrcv switch:0\n");
                  exit(1);
                }
              } // for loop 60 times
    	case 1:
    	  message.mtype = DUMMYMSG;
              strcpy(message.mtext,"Dummy Message2");
            
              for(j=0; j<20; j++){
                if(msgsnd(mid, (struct msgbuf*) &message, strlen(message.mtext)+1, 0) == -1){
                perror("Error in Main:msgsnd switch:1A\n");
                exit(1);
                }
                usleep(250);
                printf("Producer2 Sending dummy messages...\n");
              } // for loop 20 times
    
    	  message.mtype = VALIDMSG;
    	  strcpy(message.mtext,"Valid Message2");
    	  
              for(j=0; j<60; j++){
                if(msgrcv(mid, (struct msgbuf*) &message, sizeof(message.mtext)+1, DUMMYMSG, 0)){
                  printf("Producer2 Receiving...\n");
                  usleep(250);
                  if(msgsnd(mid, (struct msgbuf*) &message, strlen(message.mtext)+1, 0) == -1){
                    perror("Error in Main:msgsnd switch:1B\n");
                    exit(1);
                  } 
                  usleep(250);
                  printf("Producer2 Sending...\n");
                }
              } // for loop 60 times
            case 2:
    	  message.mtype = DUMMYMSG;
              strcpy(message.mtext,"Dummy Message3");
          
              for(j=0; j<20; j++){
                if(msgsnd(mid, (struct msgbuf*) &message, strlen(message.mtext)+1, 0) == -1){
                perror("Error in Main:msgsnd switch:2A\n");
                exit(1);
                }
                usleep(250);
    	    printf("Producer3 Sending dummy messages...\n");
              } // for loop 20 times
    
    	  message.mtype = VALIDMSG;
    	  strcpy(message.mtext,"Valid Message3");
    	  
              for(j=0; j<60; j++){
                if(msgrcv(mid, (struct msgbuf*) &message, sizeof(message.mtext)+1, DUMMYMSG, 0)){
                  printf("Producer3 Receiving...\n");
                  usleep(250);
                  if(msgsnd(mid, (struct msgbuf*) &message, strlen(message.mtext)+1, 0) == -1){
                    perror("Error in Main:msgsnd switch:2B\n");
                    exit(1);
                  } 
                  usleep(250);
                  printf("Producer3 Sending...\n");
                }
              } // for loop 60 times
             
    	case 3:
    	
              for(j=0; j<60; j++){
        	    if(msgrcv(mid, (struct msgbuf*) &message, sizeof(message.mtext)+1, VALIDMSG, 0)){
                  printf("Consumer1 receiving...\n");
                  usleep(250);
                  message.mtype = DUMMYMSG;
                  strcpy(message.mtext,"Dummy Message");
                  if(msgsnd(mid, (struct msgbuf*) &message, strlen(message.mtext)+1, 0) == -1){ // if a message is recieved, replace with a dummy
                    perror("Error in Main:msgsnd switch:3\n");
                    exit(1);
                  }
    	      printf("Consumer1 sending...\n");
                  usleep(250);
                }
              }
    	case 4:
    	
              for(j=0; j<60; j++){
        	    if(msgrcv(mid, (struct msgbuf*) &message, sizeof(message.mtext)+1, VALIDMSG, 0)){
     	      printf("Consumer2 receiving...\n");
                  usleep(250);
                  message.mtype = DUMMYMSG;
                  strcpy(message.mtext,"Dummy Message");
                  if(msgsnd(mid, (struct msgbuf*) &message, strlen(message.mtext)+1, 0) == -1){ // if a message is recieved, replace with a dummy
                    perror("Error in Main:msgsnd switch:4\n");
                    exit(1);
                  }
                  printf("Consumer2 sending...\n");
                  usleep(250);
                }
              } // for loop 60 times
    	case 5:
    
              for(j=0; j<60; j++){
        	    if(msgrcv(mid, (struct msgbuf*) &message, sizeof(message.mtext)+1, VALIDMSG, 0)){
    	      printf("Consumer3 receiving...\n");
                  usleep(250);
                  message.mtype = DUMMYMSG;
                  strcpy(message.mtext,"Dummy Message");
                  if(msgsnd(mid, (struct msgbuf*) &message, strlen(message.mtext)+1, 0) == -1){ // if a message is recieved, replace with a dummy
                    perror("Error in Main:msgsnd switch:5\n");
                    exit(1);
                  }
    	      printf("Consumer3 sending...\n");
                  usleep(250);
                }
              } // for loop 60 times
          }
        }
      }
      
      // wait for the children to exit... then kill process
      int status;
      pid_t pid;
      while (n > 0) {
        pid = wait(&status);
        printf("\nChild with PID %ld exited with status 0x%x.\n", (long)pid, status);
        --n; 
      }
    
      // remove the queue
      if (msgctl(mid, IPC_RMID, (struct msqid_ds*) 0) == -1) {
        perror("Error with removing queue in function Main\n");
        exit(1);
      }
    
      return 0;
    }

  2. #2
    Registered User
    Join Date
    Nov 2010
    Posts
    11
    Note: I did fix the break: in my cases.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    What stops each child from exiting the switch, and returning to
    for(i=0; i<n; i++)
    to create yet more children, which in turn return to
    for(i=0; i<n; i++)
    to create yet more children, which in turn return to...

    Well, you get the idea.


    Also, cases 0 to 2 and 3 to 5 are basically copy/paste code.
    Make a function out of each one, passing i as a parameter
    Code:
    switch( i ) {
      case 0: case 1: case 2:
        doProducer(i);
        _exit(0);  // end of process
        break;
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Please help me as fast as possible
    By Xbox999 in forum C Programming
    Replies: 5
    Last Post: 11-30-2009, 06:53 PM
  2. fork(), exit() - few questions!
    By s3t3c in forum C Programming
    Replies: 10
    Last Post: 11-30-2004, 06:58 AM
  3. Daemon programming: allocated memory vs. fork()
    By twisgabak in forum Linux Programming
    Replies: 2
    Last Post: 09-25-2003, 02:53 PM
  4. Tab Controls - API
    By -KEN- in forum Windows Programming
    Replies: 7
    Last Post: 06-02-2002, 09:44 AM