Compiling the wrong file?

  • A+
Category:Languages

I have 3 files — SwimMill.c, Fish.c, and Pellets.c — each of which is compiled into an executable. When SwimMill is run, it uses fork() and exec() to run Fish and Pellets. However, for some reason, when I use the terminal, compile the programs with make, and run SwimMill, the file Fish runs first. Can anybody help me?

Makefile

all: SwimMill Fish Pellets  SwimMill: SwimMill.c     gcc -o SwimMill SwimMill.c  Fish: Fish.c     gcc -o Fish Fish.c -lm  Pellets: Pellets.c     gcc -o Pellets Pellets.c 

SwimMill.c

// Uses both fish and pellets, 30 seconds, then print it out // Create pellets at random intervals, from 0x80 // Eating --> Get rid of most significant bit // Use shared memory for fish and pellet position only #include <stdio.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/types.h> #include <signal.h> #include <stdlib.h> #include <time.h> #include <unistd.h>  #define SHM_SIZE 1000  /* TODO: SwimMIll FIRST, draw and get everything working */  /* 1. Create share memory using shmget 2. Attach to shared memory using shmat 3. Do operations 4. Detach using shmdt */  void printGrid(int*); void handler(int);  int main(int argc, char* argv[]) {      printf("Hello");     signal(SIGINT, handler);      key_t key;     int shmid;     int *shm;     int timer = 0;     int fish = 0;     int pellet[20];      key = ftok("SwimMill.c", 'b'); //generate random ke     shmid = shmget(key, SHM_SIZE, IPC_CREAT|0666);     shm = shmat(shmid, NULL, 0); // Attach      // Initializing the shared memory to prevent segmentation fault     for (int i = 0; i < SHM_SIZE; i++){         shm[i] = -1;     }      int index = 0;     while(timer <= 30){         sleep(1); // Slow process down         fish = fork();         execv("Fish", argv);         pellet[index] = fork();         execv("Pellets", argv);         printGrid(shm);         printf("/n");         timer++;         index++;     }      shmdt(shm);     shmctl(shmid, IPC_RMID, NULL);     printf("Program finished! /n");     getchar(); // Pause consol     return 0; }  void printGrid(int* shm) {     int row = 10;     int column = 10;     char stream[row][column]; //2D Dimensional array, fish can only move last row of 2d       //Initializing grid first     for (int i = 0; i < row; i++) {         for (int j = 0; j < column; j++) {             stream[i][j] = '~';         }     }      //Printing out grid with fish and pellet     for (int i = 0; i < row; i++) {         for (int j = 0; j < column; j++) {             stream[i][j] = '~'; // water             for (int k = 0; k < 20; k++) {                 stream[shm[k]/10][shm[k]%10] = 'O'; // pellets                 stream[shm[0]/10][shm[0]%10] = 'Y'; // Fish             }             printf("%c ", stream[i][j]   );         }         printf("/n");     }  }  void handler(int num) {     perror(" Interrupt signal is pressed!! /n");     exit(1); } 

Fish.c

// 1 fish // Scan the entire array, and focus on one pellet // Arrange itself  #include <stdio.h> #include <sys/ipc.h> #include <sys/shm.h> #include <math.h> #include <unistd.h>  int findClosestPellet(int*); void moveLeft(int, int*); void moveRight(int, int*);  int main() {   printf("printing from fish");   key_t key = ftok("SwimMill.c", 'b');   int shmid = shmget(key, 1024, IPC_CREAT|0666);   int *shm = (int*) shmat(shmid, NULL, 0);    int fish = 94; // Middle position   shm[0] = fish; // Store first shared memor space to fish   int columnToMoveTo = 0;   while(1) {     int closestPellet = shm[findClosestPellet(shm)];     if ((closestPellet % 10) > (fish % 10) ) {       moveRight(fish, shm);     }     else if ((closestPellet % 10) < (fish % 10)) {       moveLeft(fish, shm);     }     sleep(1);   }   shmdt(shm);   return 0; }  int findClosestPellet(int* shm) {   // Using distance formula to find closest pellet   // (x2 - x1)^2 + (y2 - y1)^2   int closestPellet = 0;   int distance[20] = {0}; // Distance of all 20 pellets   int minimumDistance = 0;   // shm[1] = 11;   // shm[2] = 14;   // shm[3] = 10;   // shm[4] = 55;   int x2 =  shm[0] % 10;   int y2 = shm[0] / 10;   for (int i = 1; i < 20; i++) {     int x1 = shm[i] % 10;     int y1 = shm[i] / 10;     distance[i] = pow(x2-x1,2) + pow(y2-y1,2); // Storing them   }   minimumDistance = distance[1];    //Finding smallest distance   for (int i = 2; i < 20; i++) {     if (distance[i] <= minimumDistance) {       closestPellet = i;     }   }   printf("Closest pellet %d /n", closestPellet);   return shm[closestPellet]; }  void moveLeft(int fish, int* shm) {   if (shm[0] <= 90) {   }   else{     fish--;     shm[0]--;   } }  void moveRight(int fish, int* shm) {   if (shm[0] >= 99){   }   else{     fish++;     shm[0]++;   } } 

Pellets.c

// Multiple pellets //Process ID, position, eaten/misse #include <stdio.h> #include <sys/ipc.h> #include <sys/shm.h> #include <unistd.h> #include <stdlib.h>  void eatPellet(); void missPellet();  int main() {   key_t key = ftok("SwimMill.c", 'b');   int shmid = shmget(key, 1024, IPC_CREAT|0666);   int *shm = (int*) shmat(shmid, NULL, 0);    int i = 1; // 1 - 19 are pellets   for (; i < 20; i++) {     int pelletPosition = rand() % 9 + 0; // random number from 0 - 9     shm[i] = pelletPosition;     break;   }   while(1) {     if (shm[i] < 90) {       shm[i] += 10;     }     else if (shm[i] == shm[0]) {       eatPellet();       printf("Position: %d/n", shm[i] );       break;       // EATEN and KILL     }     else {       // KIll process, terminate       missPellet();       printf("Position: %d/n", shm[i] );       break;     }     // printf("%d/n",shm[i] );     i++;     sleep(1);   }   shmdt(shm);   return 0; }  void eatPellet() {   printf("Pellet eaten!");   printf("PID: %d /n", getpid());  }  void missPellet() {   printf("Pellet missed");   printf("PID: %d /n", getpid()); } 

For the makefile, I run "make". Then I run ./SwimMill. However, it runs Fish for some reason.

 


You're not using fork / exec correctly:

while(timer <= 30){     sleep(1); // Slow process down     fish = fork();     execv("Fish", argv);     pellet[index] = fork();     execv("Pellets", argv);     printGrid(shm);     printf("/n");     timer++;     index++; } 

Recall that the fork function returns twice: once to the parent process where it returns the child's pid, and once to the child process where it returns 0.

You're forking a new process, but not checking the return value. So both the child and the parent call execv to start the "Fish" program, so you have two copies of "Fish" running and no copies of "SwimMill" running.

You need to check the return value of fork to see if the process is the parent or the child and act accordingly.

while(timer <= 30){     sleep(1); // Slow process down     fish = fork();     if (fish == -1) {         perror("fork failed");         exit(1);     } else if (fish == 0) {         execv("Fish", argv);         perror("exec failed");         exit(1);     }      pellet[index] = fork();     if (pellet[index]== -1) {         perror("fork failed");         exit(1);     } else if (pellet[index] == 0) {         execv("Pellets", argv);         perror("exec failed");         exit(1);     }      printGrid(shm);     printf("/n");     timer++;     index++; } 

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: