1

I am currently doing the design of a counting semaphore in C++ trying to conform to the same level of standard as Java except for the InterupptedExceptions since C++ std:: threads do not support interruption. I was reading the class documentation in Java and came across two questions that really baffle me at this moment.

https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/Semaphore.html

Question 1:

regarding releasing of permits i see that a statement "There is no requirement that a thread that releases a permit must have acquired that permit by calling acquire()" In the implementation of acquire. If there is no ownership concept of acquring a permit and releasing it by same thread in design then what happens in below case.

some rogue thread simply tries to run release and it has never acquired any at all. What will get released then? does it silently return and do nothing?

Question 2:

What happens if a thread acquires a semaphore count and throws an exception where the release is simply missed out perhaps because exception propagates outside of the class of that thread function. Does this lead to permit leak in such case ?

2 Answers 2

2

some rogue thread simply tries to run release and it has never acquired any at all. What will get released then? does it silently return and do nothing?

It's better call it increment instead of release or return. You can even create a Semaphore with a negative permission:

Semaphore semaphore = new Semaphore(-1);

In this situation, if threadA try to aquire(), it will get blocked until other threads increment the permission by release() twice.

Does this lead to permit leak in such case ?

That's why it is suggested to use Semaphore with try catch finally block when the resource is limited:

semaphore.aquire();
try {

} catch () {

} finally {
    semaphore.release();
}
Sign up to request clarification or add additional context in comments.

6 Comments

I understand your point and perhaps agree on the try , catch and finally to manage the leak. Looks perfectly fine. Still Let us assume there are 10 permits and currently 10 different threads have acquired a permit and are working.5 More threads are waiting still blocked. Another bad thread [ bad design assume ] starts and calls release then what gets released and how ?
You can assume there is a counter in the Semaphore. When the bad thread call release(), the counter increment, if the incremented counter is greater than 0, one of the blocked thread get this signal and start to work. This is legal.
That then defeats the purpose of very Semphore core principle itself i.e permit limit. Now you have 10 threads that has permit and working still and another has entered and got a permit. so 11 working and using resource while there can only be a Max of 10 at any time.
@AnandKulkarni No. The permit may change. When you create a Semaphore with permits, it just represent the initial number of permits available. The programmer should be responsible for the bad thread.
"Someone can do stupid things with it" is true for basically everything. One can also do stupid things with a mutex. The statement is "if a binary semaphore is used [like this], then it acts as a mutex". Thus, this does not hold for "do stupid things".
|
0

My two cents:

some rogue thread simply tries to run release and it has never acquired any at all. What will get released then? does it silently return and do nothing?

Semaphore is not a lock, so there is no need to acquire a permit before releasing it. You can even initialize a semaphore with negative initial value. So answer to your first question is that if any thread releases permit(s), it will simply increment the permit count by the number of permits released.

Does this lead to permit leak in such case ?

On similar lines, if a thread decrements permit(s) by acquiring and fails due to any reason without releasing it, the count will stay the same. I won't call it a leak, since it is possible to have a scenario where end user simply wishes to consume the permits, without ever releasing one.

4 Comments

i got it. This simply means one has to be extra careful when using a binary semaphore as a exclusive tool for access. The danger is some one released additional permits from a rouge thread then permits will incrase more than one and where is exclusivity left then ? If an interface can break via the methods and behaviour it exposes then Binary Semaphore != lock at all [ unless used properly knowing the limitations ]
Yes, the exclusivity needs to be guaranteed by the user of your interface. It is beyond responsibility of your interface to ensure that.
What happens in case of fairness setting where threads are queued and waiting , the front of the queue is a bulk request of 2 permits but only 1 is available and second item in the queue is a request for 1 permit. Does FIFO mean the whole queue is blocked until first items request of all permits is satisfied ?
Yes, subsequent threads in queue will wait til first one is served.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.