Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Semaphore - What is the use of initial count?

People also ask

Where do we use counting semaphore?

Semaphores are typically used to coordinate access to resources, with the semaphore count initialized to the number of free resources. Threads then atomically increment the count when resources are added and atomically decrement the count when resources are removed.

Why is counting semaphore a good concurrency mechanism?

Semaphores are a fine-grained mechanism for controlling concurrency, and as such they offer the potential of great performance at the expense of difficult use. Not only are race conditions difficult to detect, but also the mutual exclusion required to eliminate them can produce deadlocks or starvation.

Can semaphore be negative?

If the new value of the semaphore variable is negative, the process executing wait is blocked (i.e., added to the semaphore's queue). Otherwise, the process continues execution, having used a unit of the resource. signal: Increments the value of semaphore variable by 1.


Yes, when the initial number sets to 0 - all threads will be waiting while you increment the "CurrentCount" property. You can do it with Release() or Release(Int32).

Release(...) - will increment the semaphore counter

Wait(...) - will decrement it

You can't increment the counter ("CurrentCount" property) greater than maximum count which you set in initialization.

For example:

SemaphoreSlim^ s = gcnew SemaphoreSlim(0,2); //s->CurrentCount = 0
s->Release(2); //s->CurrentCount = 2
...

s->Wait(); //Ok. s->CurrentCount = 1
...

s->Wait(); //Ok. s->CurrentCount = 0
...

s->Wait(); //Will be blocked until any of the threads calls Release()

So, I am really confused about the significance of initial count?

One important point that may help here is that Wait decrements the semaphore count and Release increments it.

initialCount is the number of resource accesses that will be allowed immediately. Or, in other words, it is the number of times Wait can be called without blocking immediately after the semaphore was instantiated.

maximumCount is the highest count the semaphore can obtain. It is the number of times Release can be called without throwing an exception assuming initialCount count was zero. If initialCount is set to the same value as maximumCount then calling Release immediately after the semaphore was instantiated will throw an exception.


How many threads do you want to be able to access resource at once? Set your initial count to that number. If that number is never going to increase throughout the life of the program, set your max count to that number too. That way, if you have a programming error in how you release the resource, your program will crash and let you know.

(There are two constructors: one that takes only an initial value, and one that additionally takes the max count. Use whichever is appropriate.)


If you wish that no thread should access your resource for some time, you pass the initial count as 0 and when you wish to grant the access to all of them just after creating the semaphore, you pass the value of initial count equal to maximum count. For example:

hSemaphore = CreateSemaphoreA(NULL, 0, MAX_COUNT, NULL) ;

//Do something here
//No threads can access your resource

ReleaseSemaphore(hSemaphore, MAX_COUNT, 0) ;

//All threads can access the resource now

As quoted in MSDN Documentation- "Another use of ReleaseSemaphore is during an application's initialization. The application can create a semaphore with an initial count of zero. This sets the semaphore's state to nonsignaled and blocks all threads from accessing the protected resource. When the application finishes its initialization, it uses ReleaseSemaphore to increase the count to its maximum value, to permit normal access to the protected resource."


This way when the current thread creates the semaphore it could claim some resources from the start.