ptg10805159
584 Interprocess Communication Chapter 15
s_alloc()
{
struct slock *sp;
static int cnt;
if ((sp = malloc(sizeof(struct slock))) == NULL)
return(NULL);
do {
snprintf(sp->name, sizeof(sp->name), "/%ld.%d", (long)getpid(),
cnt++);
sp->semp = sem_open(sp->name, O_CREAT|O_EXCL, S_IRWXU, 1);
}while ((sp->semp == SEM_FAILED) && (errno == EEXIST));
if (sp->semp == SEM_FAILED) {
free(sp);
return(NULL);
}
sem_unlink(sp->name);
return(sp);
}
void
s_free(struct slock *sp)
{
sem_close(sp->semp);
free(sp);
}
int
s_lock(struct slock *sp)
{
return(sem_wait(sp->semp));
}
int
s_trylock(struct slock *sp)
{
return(sem_trywait(sp->semp));
}
int
s_unlock(struct slock *sp)
{
return(sem_post(sp->semp));
}
Figure 15.35 Mutual exclusion using a POSIX semaphore
We create a name based on the process ID and a counter.Wedon’t bother to protect
the counter with a mutex, because if two racing threads calls_allocat the same time
and end up with the same name, using theO_EXCLflag in the call tosem_openwill
cause one to succeed and one to fail witherrnoset toEEXIST, so we just retry if this
happens. Note that we unlink the semaphoreafter opening it. This destroys the name
so that no other process can access it and simplifies cleanup when the process ends.