Semaphore - What is the use of initial count?

38,276

Solution 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()

Solution 2

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.

Solution 3

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.)

Solution 4

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."

Solution 5

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

Share:
38,276
leon luo
Author by

leon luo

I come from non CS background. Currently I program in iOS using objective-C

Updated on July 08, 2022

Comments

  • leon luo
    leon luo almost 2 years

    http://msdn.microsoft.com/en-us/library/system.threading.semaphoreslim.aspx

    To create a semaphore, I need to provide an initial count and maximum count. MSDN states that an initial count is -

    The initial number of requests for the semaphore that can be granted concurrently.

    While it states that maximum count is

    The maximum number of requests for the semaphore that can be granted concurrently.

    I can understand that the maximum count is the maximum number of threads that can access a resource concurrently. But, what is the use of initial count?

    If I create a semaphore with an initial count of 0 and a maximum count of 2, none of my threadpool threads are able to access the resource. If I set the initial count as 1 and maximum count as 2 then only thread pool thread can access the resource. It is only when I set both initial count and maximum count as 2, 2 threads are able to access the resource concurrently. So, I am really confused about the significance of initial count?

    SemaphoreSlim semaphoreSlim = new SemaphoreSlim(0, 2); //all threadpool threads wait
    SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1, 2);//only one thread has access to the resource at a time
    SemaphoreSlim semaphoreSlim = new SemaphoreSlim(2, 2);//two threadpool threads can access the resource concurrently
    
  • leon luo
    leon luo over 13 years
    So, you mean when I want two worker threads to access the resource I should change the initial count?
  • Emond
    Emond over 13 years
    No. It is the current thread that claims a count. If you do not want the current thread to claim any access pass 0 or use the overload with one parameter.
  • ChrisF
    ChrisF over 13 years
    Your code will be better presented in the answer rather than as a comment.
  • Abhineet
    Abhineet about 12 years
    Sorry, I gave you the example in C++ though can clear the doubt.
  • Philip Tenn
    Philip Tenn about 10 years
    This is so helpful! I had been thinking about Semaphores backward, as in initialCount being the number of initial BLOCKED resources, not the number of resources that are available immediately. Thank you.
  • BlueStrat
    BlueStrat over 7 years
    LOL it is probably the 5th time that I reach this same answer because the constructor's documentation always confuses me on which values to set. Cheers
  • BlueStrat
    BlueStrat over 7 years
    @PhilipTenn, I agree - the documentation is not clear on this respect
  • IronHide
    IronHide about 7 years
    I agreed, they should change that variable name or update the docs
  • Michał Turczyn
    Michał Turczyn almost 6 years
    @Sandbox you should accept this answer IMO, as it really explains the meaning of initialCount parameter.
  • shelbypereira
    shelbypereira over 3 years
    The quote about initialization is very helpful, although other answers explain how semaphoreSlim works, this is the only answer that has a very useful example use case for this somewhat obscure functionality.
  • Keith Bluestone
    Keith Bluestone over 2 years
    Excellent answer, definitive!