All the best to everyone
The Problem
When using Base.Semaphore to limit the number of concurrently executing heavy tasks, there is a fundamental difference in the behavior of the two approaches:
Option A (Syntactic sugar do):
Base.acquire(sem) do
data = take!(chan)
@spawn handle(data)
end
Option B (Explicit acquire/release via closure) in asynchrony:
Base.acquire(sem)
data = take!(chan)
@spawn try
handle(data)
finally
Base.release(sem)
end
Option A works.
Option B, at least in complex hybrid parallelization schemes, leads to erratic semaphore behavior and stalling.
And I can’t understand whether this is a bug or whether option A is ideologically and/or practically the only correct one?