I saw some code where a sem_init was called with a value of 0.
I didn't quite understand what this meant. I understand that semaphores can be used to protect shared data, in that we allow just one thread to access the data. And, the way to do it is using sem_init with value 1.
Can anyone please explain what a 0 init(ed) semphore means?
Any explanation would be helpful.
If you initialise a semaphore value to zero, it means that when you look at it, it will have the value zero.
That's it. All the rest is interpretation.
If you have decided that you want "zero" to mean "the data this semaphore is referring to is not being used, so you can set the value of the semaphore to one and then you can go ahead and use the data" then that's what it means.
If you have decided that you want "zero" to mean "the data this semaphore is referring to is being used, so you can't have the data" then that's what it means.
If you have decided that this is not a binary semaphore (i.e. not a simple yes/no), but a counting semaphore, then zero might mean "right now, there are zero accesses to this data going on" or zero might mean "there are no resources available so you can't have any".
If you're using a semaphore system that someone else wrote, they will probably have already decided what a zero semaphore means and you should check the documentation.
It is common to decide to interpret a zero (or other such nullesque value) valued semaphore to mean "nobody is using this data right now".
A semaphore initialized with 1 and used to protect shared memory is a mutex semaphore, the most common use case for a semaphore.
There are other use cases, a process sequence for example, where it does not have to be initialized with 0.
A longer explanation here
From the linux manpage sem_overview(7) which i consider a reliable source of information.
A semaphore is an integer whose value is never allowed to fall below zero. Two operations can be performed on semaphores: increment the semaphore value by one (sem_post(3)); and decrement the semaphore value by one (sem_wait(3)). If the value of a semaphore is currently zero, then a sem_wait(3) operation will block until the value becomes greater than zero.
The only restriction of a semaphore is that it's value can not be less than zero.
If the semaphore is 0, anyone using sem_wait will have to wait until it becomes greater than 0.
The 0 initied semaphore indicates that any process that uses sem_wait will have to wait until someone uses sem_post
The case you mentioned of the semaphore being initialized with 1, used to protect shared memory segments is the case of a mutex, or semaphore for mutual exclusion. You could also achieve this initializing the semaphore to 0 and dong sem_post after the initialization.
But that is not the only use case for a semaphore, consider the case of using a semaphore to make a process (or thread if you want) sequence (process B must wait for process A to finish some operation, not necessarily inside a shared memory segment). Here you can init the semaphore with 0.
You then have 2 possibilities.
A posts and B waits
The semaphore value is 0, A uses sem_post and it becomes 1.
The semaphore value is 1, B uses sem_wait. Because it is greater than 0, it does not have to wait and decreases the value again to 0.
B waits and A posts
The semaphore value is 0, B uses sem_wait. B will wait for A to release it.
The semaphore value is 0, A uses sem_post and it becomes 1. B stops waiting and decreases it to 0.