Reputation: 627
I am seeing a value of 0 being used in a piece of code. We use a value of 1 for a binary semaphore and a value of N for a counting semaphore. Somehow the value of 0 isn't making sense to me.
/* Initialise the semaphore to be blocked. */
sem_t sem;
sem_init(&sem, 0, 0);
The code is in C programming. Then as usual we have sem_wait, sem_post and sem_destroy in other places within the code.
If using either 0 or 1 is fine, then why doesn't this program run -
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
sem_t mutex;
void* thread(void* arg)
{
//wait
sem_wait(&mutex);
printf("\nEntered..\n");
//critical section
sleep(4);
//signal
printf("\nJust Exiting...\n");
sem_post(&mutex);
}
int main()
{
sem_init(&mutex, 0, 0);
pthread_t t1,t2;
pthread_create(&t1,NULL,thread,NULL);
sleep(2);
pthread_create(&t2,NULL,thread,NULL);
pthread_join(t1,NULL);
pthread_join(t2,NULL);
sem_destroy(&mutex);
return 0;
}
The same would run if sem_init was done with sem_init(&mutex, 0, 1);
Upvotes: 0
Views: 13346
Reputation: 384
The metaphor for a semaphore is a library with N copies of "Moby Dick". You can only check out N times and then check out waits for a check in. If you have 1 copy, it behaves like a mutex. Starting at 0 is just starting locked, a reasonable default. You can tell it a larger sum before it gets tested. I would say how, but then I would have to google up the right man pages, which is what I recommend to all my students! You cannot remember it all, but you should know a little and how to find the rest! Note that some semaphores live in memory for thread use, others in the file system for inter-process use.
Upvotes: 2
Reputation: 386551
While both values are allowed and perfectly reasonable, that doesn't mean they are interchangeable.
Imagine if you wanted Thread 2 to wait for Thread 1 to complete it's work before proceeding. You could use the following:
main:
sem_t sem;
sem_init(&sem, 0, 0);
Thread 1:
do_work();
sem_post(&sem);
Thread 2:
do_some_work();
// Wait for Thread 1 to complete before proceeding.
sem_wait(&sem);
do_other_work();
As you can see, initializing a semaphore to zero can be perfectly reasonable. That doesn't mean it does the same thing as initializing it to one. Your program is buggy because your thread waits for the value of the semaphore to be raised above zero, but nothing ever does that.
Upvotes: 4
Reputation: 181459
I am seeing a value of 0 being used in a piece of code. We use a value of 1 for a binary semaphore and a value of N for a counting semaphore. Somehow the value of 0 isn't making sense to me.
0 is a value that every semaphore can take. Initializing a semaphore with that value is therefore perfectly reasonable.
If using either 0 or 1 is fine, then why doesn't this program run [...]
Just because it is reasonable in general to initialize a semaphore to zero does not mean that doing so is appropriate for a given particular purpose.
The value of a semaphore at any given time affects its behavior. In particular, sem_wait()
attempts to decrement a semaphore without reducing its value below zero, blocking until it can do so. Thus, if you initialize a semaphore with value zero then every thread that attempts to sem_wait()
on it will block until some thread increases its value via sem_post()
. If you are using the semaphore as a mutex, as the example code does, then you could characterize that as the mutex being initially locked.
Upvotes: 6
Reputation: 31609
sem_init
only sets the initial value.
If during the lifetime of the semaphore its value won’t exceed 1, you can call it a binary semaphore, and counting semaphore otherwise.
The initial value is just the first value that the semaphore holds, not the maximum.
Upvotes: 1