the semaphore set must be initialized using semget(); the semaphore creator can change its ownership or permissions using semctl(); and semaphore operations are performed via the semop()
Three features contribute to this unnecessary complication:
A semaphore counter is not just a single value. It's rather a set of one or more values, and the exact number of values is specified upon semaphore creation.
The creation of a semaphore is independent of its initialization. This is a fatal flaw, since we cannot atomically create a new semaphore set and initialize all the values in the set: a competing process may sneak in and access the semaphore after creation but before initialization, thus finding semagarbage.
A semaphore must be explicitly destroyed when the shared resource is no longer necessary, since the systemwide total number of semaphore sets is limited.
semget(key, nsems, flags) => semid ; semid is like a file descriptor and can be used from the same process to access that semaphore set.. but, the key is like file path which processes share to gain access to the same semaphore set.... Cooperating processes wishing to access the semaphore set must use the same key, much like a file name is used to store on disk shared data by cooperating processes.
flag = IPC_PRIVATE creates a private semaphore set that is accessible only to the current process. Hence, no need for a key to be remembered and other processes cannot access this semaphore.
Use int semctl(int semid, int semnum, int cmd, ...); to initialize the nth semaphore.
Performing a WAIT or SIGNAL
int semop(int semid, struct sembuf *sops, size_t nsops);
sembuf.semop = 0 waits on 0; > 0 increments counter by that amount; <>
int ret = semctl(semid,0,IPC_RMID); //removing the 0th semaphore in the set
if you don't do this we will leak..
How many can we allocate ????
Typically, 128 arrays of maximum 256 semaphores each
So, looking at all these, It appears that implementing a shared memory infrastructure using System V Semaphore is a real pain ... :(
The problems include
-- Cleaning up of Global Semaphores after a total system failure.
Hashing algorithms can identify which shared memory segments are yours.
-- Clean up of local or ipc_private semaphores, allocated in each process
This is kind of tricky. The best way would be to not use private semaphores., but lease semaphores out of the global semaphore array..