2

I've got a project in which I have to use SYS V semaphores. I've got several processes which share a semaphore (using the same key) and initialize it with this code:

bool semaphore_init(semaphore_id_t* sem, int sem_value, key_t key)
{
    /* Try to get a semaphore, to check if you will be an owner */
    *sem = semget(key, 1, IPC_CREAT | IPC_EXCL | 0666);
    if (*sem == -1)
    {
        if (errno == EEXIST)
        {
            /* We are not owners, get semaphore without exclusive flag */
            *sem = semget(key, 1, IPC_CREAT | 0666);
            if (*sem == -1) return false;
        }
        else return false;
    }
    else
    {
        /* We are owners, initialize semaphore */
        int return_value = semctl(*sem , 0, SETVAL, sem_value);
        if (return_value == -1) return false;
    }

    return true;
}

My problem is: I want to remove this semaphore when all processes using it will terminate. Using:

semctl(*sem, 0, IPC_RMID)

is not an option. It deletes semaphore instantly and other processes got undefined behaviour. I just can't find correct way to do it with SYS V API.

1 Answers1

0

You can use reference counting. Just have each process increment the ref counter after semaphore init and decrement it when the process terminates. The last one to decrement it to 0 will also remove it, or have the main process clean it when it knows all other processes have terminated.

You'll probably also need another locking mechanism to synchronize access to the reference counter, which you will probably create/remove in the main process that spawns and waits for other processes.

Also, watch out for dangling references if your processes can terminate abnormally.

Eran
  • 719
  • 4
  • 13
  • 1
    The problem is library is decentralized. As you said I would have to use another semaphore for reference counting. But who would free it? – Przemysław Lenart Jan 16 '13 at 15:26