I was going through a code (a solution to dinning philosophers problem ) and comes the part where the programmer initializes his semaphores, However before he initializes each one , he first unlink it.
int sems_init(t_args *args)
{
sem_unlink("forking");
args->sem_forks = sem_open("forking", O_CREAT, 0644,
args->philo_amount);
if (args->sem_forks == SEM_FAILED)
return (1);
sem_unlink("writing");
args->sem_write = sem_open("writing", O_CREAT, 0644, 1);
if (args->sem_write == SEM_FAILED)
return (1);
sem_unlink("meal");
args->sem_meal = sem_open("meal", O_CREAT, 0644, 1);
if (args->sem_meal == SEM_FAILED)
return (1);
return (0);
}
I googled it and it seems there isn't any resource in the SO community that actually mention this one. or at least i didn't find it.
The semaphores initialization isn't called in a loop and it is not called before this initialization (this is the first time they're initialized in the code). which amplify my confusion, i tried to comment the sem_unlink()
part from the code and it stops working at it should, that is the unlink part is doing something , the question why we delete a semaphore before initialize it even though the initialization might be the first one.
CodePudding user response:
why we delete a semaphore before initialize it even though the initialization might be the first one.
Because named semaphores such as are created by sem_open()
have kernel persistence. That's part of the point of naming them. They live until either
- they are unlinked and no processes remain that have them open, OR
- the system is shut down.
If you want to be sure you are creating a new (named) semaphore instead of opening an existing one then unlinking the name before the sem_open()
call makes that pretty likely. If you want to be certain, however, then you should also add O_EXCL
to the flags. That will cause sem_open()
to fail if a semaphore with the given name already exists, such as if another process created one between the sem_unlink()
and the sem_open()
.
Note also that semaphore names should begin with a /
(see sem_overview(7)). Some libraries don't enforce that, but you should not gratuitously introduce a portability issue by omitting it.
On the other hand, if you want a semaphore for a single process only, whose lifetime is bounded by its host process, then you are just making life hard on yourself by using named semaphores. You would be better off in that case with anonymous ones, declared as objects of type sem_t
and initialized via the sem_init()
function instead of sem_open()
. That would moot all the persistence and unlinking questions.