Reputation: 1728
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
Reputation: 36402
You can do something like the following:
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()
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
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