Maciej Stachowski
Maciej Stachowski

Reputation: 1728

Who initializes semaphores?

So, the problem is: I'm writing a "chat simulator" for my university project. Not getting into too much detail, the client can be run multiple times, and all the instances use the same segment of shared memory guarded by a semaphore (among other things).

The clients enter and exit the system at unknown times. When the first client enters the system, it should create a semaphore, use the shared memory and release. If any other client enters the system, however, it has to wait on the semaphore before acquiring a shared memory access.

Now, I feel like I'm missing something obvious - how do I initialize the semaphore? If I use semget(42, 1, IPC_CREAT), the resulting semaphore will most likely be 0 - but I can't raise it to initialize it, since the 0 might mean that there's a process already in the critical section. In other words, I have no idea whether I've just created the semaphore with default value 0, or if there's a process waiting on the semaphore.

In pseudocode:

if(semaphore_not_exists(42))
{
    create_sem;
    raise_sem;
}
else
{
    get_sem_handle;
}
wait_on_sem;
critical_section;
release_sem;

So, how do I make sure that the semaphore has not yet been created by another process, so that it's safe to initialize it? If I use IPC_EXCL, the request will fail, but I don't know what I should do next.

Upvotes: 3

Views: 495

Answers (2)

Hasturkun
Hasturkun

Reputation: 36402

You can do something like the following:

  1. Call semget(key, nsems, IPC_CREAT | IPC_EXCL). If this succeeds you have now created a new semaphore set, which you should then set via semctl()
  2. If previous semget() failed, call semget() again, without the IPC_EXCL flag.

I'd also recommend using a lockfile (via flock() or similar) to ensure that the semaphore set isn't used until it is initialized.

Upvotes: 3

UmNyobe
UmNyobe

Reputation: 22890

i think all the users of the semaphore need to obtain it already initialized. Otherwise the initialization of the semaphore itself is subject to race conditions. you can have a daemon which initialize the semaphore at system bootstrap and take care of

create_sem;
raise_sem;

while clients just execute

get_sem_handle;

Upvotes: 0

Related Questions