0

I want to create two child processes with some iterations in them so that iteration l in process X always executes after iteration l+1 in process Y.

#include <stdio.h>
#include <unistd.h>
#include <bits/stdc++.h>
#include <sys/wait.h>
#include <semaphore.h>


using namespace std;

sem_t mut;

int x = 2;
int main()
{
    int cpX = fork();
    sem_init(&mut, 1, 1);
    if (cpX == 0)
    {
        //child A code
        for (int i = 0; i < 10; i++)
        {
            sem_wait(&mut);
            cout << "Inside X:" << getpid() << ", " << i << '\n';
            sleep(rand() % 5);
        }
        
        exit(0);
    }
    else
    {
        int cpY = fork();
        if (cpY == 0)
        {
            //child B code
            for (int i = 0; i < 10; i++)
            {
                cout << "Inside Y:" << getpid() << ", " << i << '\n';
                sleep(rand() % 5);
                sem_post(&mut);
            }
            //sem_wait(&mut);
           exit(0); 
        }
        else
        {
            //sleep(50);
            
            //wait(NULL);
            //wait(NULL);
            exit(0);
            // wait(NULL);
        }
    }
}

However here, X executes once, and then Y starts executing and X never executes again. Why is this happening?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 1
    Maybe because the first child process gets forked off ***before*** the semaphore is initialized? – Sam Varshavchik Jan 04 '21 at 03:55
  • Hi, I did that too, but it didn't help. I think the issue is that semaphores created with sem_init have to be located in a shared memory space. – Titir Adhikary Jan 04 '21 at 04:22
  • 1
    Does this answer your question? [How to share semaphores between processes using shared memory](https://stackoverflow.com/questions/8359322/how-to-share-semaphores-between-processes-using-shared-memory) – kaylum Jan 04 '21 at 04:39

1 Answers1

0

The parent/child during a fork is doing a copy so they are not referring to the same semaphore object. Hence, mut is not shared as what you assumed. Your snippet is near correct you just need to do minor changes to work as you expect.

Since you are using an unnamed semaphore, you need to instantiate the semaphore object in a shared area:

#include <sys/mman.h>

sem_t *mut = (sem_t*)mmap(NULL, sizeof(*mut), PROT_READ |PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS, -1, 0);
sem_init(mut, 1, 1);

With this minor adjustments, your snippet above now works as expected as they are now referring to the same semaphore object.

Also, some tips: sem_post is an unblocking call, whereas sem_wait is a blocking call. You need to be also aware that a signal sent by sem_post could get lost when nobody is waiting on the semaphore during that moment.

The best reference of this kinds of things is Unix Network Programming: Interprocess Communication by Richard Stevens

daparic
  • 3,794
  • 2
  • 36
  • 38