Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Who initializes semaphores?

Tags:

c

posix

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.

like image 802
Maciej Stachowski Avatar asked Jun 16 '26 20:06

Maciej Stachowski


1 Answers

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.

like image 188
Hasturkun Avatar answered Jun 25 '26 20:06

Hasturkun