0

I want the following output from parent process and child process alternatively

parent : 2 x 1 = 2
child : 2 x 2 = 4
parent : 2 x 3 = 6
 .
 .
child : 2 x 10 = 20

I've tried the code below using semaphores.

#include <stdio.h>
#include <semaphore.h>
#include <unistd.h>

sem_t mutex_odd,mutex_even;

int main()
{  
   int o=1;e=2;
   pid_t pid = fork();
   sem_init(&mutex_odd,0,1);
sem_init(&mutex_even,0,1);
if(pid>0)
{
while(o<=9)
{
  sem_wait(&mutex_even);
  printf("parent : 2 x %d = %d\n", o, 2*o); 
  o+=2;
  sem_post(&mutex_odd);
}
}
else if(pid == 0)
{
while(e<=10)
{
   sem_wait(&mutex_odd);
   printf("parent : 2 x %d = %d\n", e, 2*e); 
   e+=2;
   sem_post(&mutex_even);
}
}
else
{
   printf("Child process couldn't be created!\n");
   exit(0);
}
return 0;
}

But the output is as shown below. Control just stays there without terminating the program.

parent : 2 x 1 = 2
child : 2 x 2 = 4

Is this a deadlocked state? How to solve this problem?

Tanveer Badar
  • 5,438
  • 2
  • 27
  • 32
  • 3
    You're initializing both semaphores after the fork, so they'll be completely different entities and each process will be signalling/waiting into thin air. Try initializing both _before_ the fork and see how you get on. – Edd Inglis Nov 28 '19 at 09:41

1 Answers1

1

When a parent process forks, its child inherits a COPY of the values that the parent was managing. A copy doesn't use the same physical memory area; also the memory pointers, although it seems they have the same address value, don't point the same physical memory area.

The way to obtain that the parent and the child share memory is to use IPC (inter process communication) functions.

The program below uses the IPC functions: shmget, shmat to allocate the memory to manage the semaphores (variable mutex) and uses the functions shmdt to "deallocate" the mutex array pointer and smdctl to remove the allocated physicall memory.

An other issue of your code is the initialization of the semaphore. The second parameter (pshared), when the sharing is between forked processes, shall be 1. With the purpose to avoid sync issues the third parameter (value) it's better it's set to 1 for the mutex the parent process waits for and set to 0 for the mutex the child process waits for.

#include <stdio.h>
#include <semaphore.h>
#include <unistd.h>

#include <pthread.h>
#include <sys/wait.h>

#include <sys/ipc.h>
#include <sys/shm.h>

    static sem_t * mutex;

    int main()
    {
        int o=1,e=2,r;
        pid_t pid;
        int shmid=0;

        shmid=shmget(0,sizeof(mutex)*2 + SHMLBA, IPC_CREAT | SHM_R | SHM_W);
        if (shmid==-1) {
            perror("shmget");
            return errno;
        }

        mutex=shmat(shmid, NULL, 0);
        if (mutex== (void *) -1){
            perror("shmat");
            return errno;
        }

        r=sem_init(&mutex[0],1,1);
        if (r) {
            perror("m0");
            return errno;
        }

        r=sem_init(&mutex[1],1,0);
        if (r) {
            perror("m1");
            return errno;
        }

        pid=fork();
        if(pid>0)
        {
            while(o<=9)
            {
                sem_wait(&mutex[0]);
                printf("parent : 2 x %d = %d\n", o, 2*o);
                o+=2;
                sem_post(&mutex[1]);
            }

            // Waits end of
            waitpid(pid,NULL,0); // Waits end of child
            puts("End");

            r=shmdt(mutex);                   // Free memory
            if (r)
                perror("shmdt");

            r=shmctl(shmid,IPC_RMID,NULL);    // Remove map id.
            if (r)
                perror("shmctl");
        }
        else if(pid == 0)
        {
            while(e<=10)
            {
                sem_wait(&mutex[1]);
                printf("child : 2 x %d = %d\n", e, 2*e);
                e+=2;
                sem_post(&mutex[0]);
            }
        }

        /*---------------------*/
        else
        {
            perror("Child process couldn't be created!\n");
            exit(0);
        }
        return 0;
    }
Sir Jo Black
  • 2,024
  • 2
  • 15
  • 22