Linux – How to use named semaphore from child

cforklinuxsemaphore

So basically I want to suspend a bit the child process after it's creation, just so the parent prepare some data for it in a shared memory. I'm trying to use a semaphore, as suggested here: How to share semaphores between processes using shared memory.

Problem nr 1: the child can't open the semaphore.

Problem nr 2: strerror returns an int, but man strerror clearly says it returns an char *.

To avoid "what have you tried":

sem = sem_open("/semaphore", O_CREAT, 0644, 0);    

for (i = 0; i < num; i++)                                        
{   
    pid = fork();                                                               

    if (pid == 0)                                                               
    {   
        sem = sem_open("/semaphore", 0);                                        
        if (sem == SEM_FAILED)                                                  
        {   
            printf( "Error : %d\n", strerror(errno ));
            exit(0);                                                            
        }
        sem_wait(sem);   
        exit(0);                                                                
    }                                                                                                                       
}

prepare_data_for_child_processes();

for (i = 0; i < mpi_comm_world->np; i++)
    sem_post(sem);

sem_close(sem);
sem_unlink("/semaphore");

Best Answer

You don't need the children to call sem_open() at all — they can simply sem_wait() on their inherited sem_t handle.

You probably want to restrict the semaphore to just your "work crew". In that case, the parent should open the semaphore exclusively (O_EXCL) with restrictive permissions, and then unlink it right away. This will prevent honest mistakes from corrupting your semaphore's state (but won't protect against hostile programs):

...
sem = sem_open("/semaphore", O_CREAT|O_EXCL, 0644, 0); /* Note O_EXCL */
sem_unlink("/semaphore");

for (i = 0; i < num; i++) {
  if (fork() == 0) {
    sem_wait(sem);
    /* Do some work */
    exit(0);
  }
}

prepare_data_for_child_processes();

for (i = 0; i < mpi_comm_world->np; i++)
    sem_post(sem);

sem_close(sem);

Now, if your implementation supports it, you should instead sem_init(1, 0) in shared memory. That will give you a truly anonymous semaphore restricted just to your work crew.

(And, yes, problem #2 is a missing include.)