0

So i was experimenting on how to use fork and semaphores for a homework and it seems everytime i run the program fork always returns a number >0, while what i wanted was to first have several processes be made then be stopped using semaphores and then have some of them restart again.

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>

int     main(int argc,char *argv[])
{
int i,count;
 count = 0;
 pid_t  *Pc;
 Pc=(pid_t *) malloc((argc-2)*sizeof(pid_t));
 sem_t *sem;
  sem = (sem_t *) malloc((argc-2)*sizeof(sem_t));
     for (i = 0; i <= argc-2; i++){
      sem_init(&sem[i], 0, 0);
 }
     for (i =0; i<=argc-2; i++){
                    Pc[i] = fork();
                    if (Pc[i] == 0){
                   printf(" child");
                    sem_wait(&sem[i]);
                    printf("Experiment was a success!");
          }
           if (Pc[i]>0){
             printf("Parent");
}
    }
        for (i =0; i<=argc-2; i++){
           if (Pc[i] > 0)
            count++;
        }

    for (i= 0; i<=3; i++){
            if  ( count ==  argc-2){
            sem_post(&sem[i]);
 }
    }

}

nameofprogram 1 2

prints: Parent Child Parent Child

Geo Ha
  • 11
  • 3
  • Remember that stdout typically is line buffered. If your messages don't show up as expected, add some "\n", as in printf(" child\n"), or use fflush, as in fflush(stdout). – Thomas Padron-McCarthy Nov 27 '14 at 16:52
  • Messages come out but it's always Parent what is being printed. Child or Experiment was a success! never are. Which, makes me wonder what is wrong with it :/ – Geo Ha Nov 27 '14 at 16:55
  • So after adding new lines and running it with nameofprogram 1 2 i got Parent Child Parent Child yet again the message after child processes should be restarting didn't show up... i am suspecting Parent is getting printed first cause the parent process is faster, not sure though. – Geo Ha Nov 27 '14 at 17:11

2 Answers2

2

You need to read the man page for sem_init(). The type of semaphore you are creating right now is not shared across processes. This requires a non-trivial change to your program, because you also need to set up shared memory. Refer to this question for a lengthy explanation of how to make your program work.

Community
  • 1
  • 1
JS1
  • 4,745
  • 1
  • 14
  • 19
2

When a program calls fork, a new process is created with a new exact copy of the memory space. This mean that sem in your child process is not the same as sem in your parent process. So, when you call sem_post, you child process can not be notified of the change and get out of the wait function.

To solve this, you have different possibilities:

  • Create a shared memory which can be read by all your processes and create this semaphore in this shared memory, as already suggested.

  • Use named semaphores with sem_open. This kind of semaphore can be shared across different processes as it work like a file handle. This seems to be an easier way if you only need a shared semaphore (example here). You will have to generate a unique name for each semaphore in your array (may be only one semaphore on which you call sem_post multiple times would be enough for your use).

  • Keep your semaphores and use threads instead of processes (but I guess your homework is about processes so this may not be an option for you)

Community
  • 1
  • 1
archz
  • 1,073
  • 13
  • 19