[erlang-questions] Semaphores
ok
ok@REDACTED
Thu Mar 15 07:10:52 CET 2007
On 15 Mar 2007, at 3:17 pm, Danesh Daroui wrote:
> I have seen (even posts in this mailing list) that there is a need
> to have Semaphores
> in Erlang
This is debatable.
Semaphores are a rather dangerous and low level construction,
and Erlang is not really supposed to be a dangerous and low level
language.
> and since Erlang offers concurrency, Semaphores can be useful in
> data sharing.
But for most purposes, Erlang *doesn't* share data.
> I would be glad to have your feedbacks.
feedback is a mass noun.
Source files should be kept to a maximum width of 80 columns;
the RETURN key is there for a reason and should be used often.
Source code should be indented using your text editor's indentation
features, NOT one tab per tab stop. 8-column indentations (what you
get when you use the tab key) are eye-jarring.
Just like the RETURN key, the space bar is there on your keyboard for
a reason. It should be used between "words"; see the Ada Quality &
Style
Guidelines for some nearly excellent advice about this. Infix operators
like -> are usually best treated as words, punctuation marks are usually
best treated like punctuation marks in English.
Unlike Smalltalk, which originated the practice because the Smalltalk
character
set didn't *have* any suitable character like "_", Erlang *does* have
"_" and
*does* allow it in multi_word_identifiers. (As, for that matter,
does modern
Smalltalk.) BaStudlyCapsIsNotVeryEasyToRead.
Your new function would be better as
new(Initial_Count) when is_integer(Initial_Count), Initial_Count
>= 0 ->
spawn(fun () -> semaphore_loop(Initial_Count) end).
There are a number of really basic problems with semaphores.
For one thing, unless you speak Dutch, 'p' and 'v' have no intrinsic
meaning
to you. (If I say that I think 'p' means 'passieren', that just
shows you that
my ignorance of Dutch is unbounded.) Even 'increment' and
'decrement' would be
better names (whichever way around they go), or 'acquire'/'release'.
One big problem is that it is too easy to forget to increment the
counter again.
Smalltalk handles this with 'aSemaphore critical: aBlock'; the Erlang
equivalent
would be
critical(Semaphore, Fun) ->
p(Semaphore),
Answer = Fun().
v(Semaphore),
Answer.
BUT with extra stuff in there to catch exceptions, release the
semaphore, and
re-raise the exceptions. Eeek.
Oh heck, I leave you to the abundant literature on semaphores to find
out why
semaphores have a bad name.
There really isn't much point in writing
case (SemValue>0) of
true -> ~a~
false -> ~b~
end
First, the parentheses are worse than useless here.
Second, you really need spaces around the > because it is hard to see
without them.
Third, what's wrong with
if Count > 0 ->
~a~
; Count <= 0 ->
~b~
end
making it completely obvious when each case applies?
Above all, all you really want to do is this:
semaphore_loop(Count) ->
receive
{acquire,Pid} when Count > 0 ->
Pid!granted,
semaphore_loop(Count - 1)
; release ->
semaphore_loop(Count + 1)
; stop ->
ok
end.
new(Initial_Count) when is_integer(Count), Count >= 0 ->
spawn(fun () -> semaphore_loop(Initial_Count) end).
acquire(Semaphore) ->
Semaphore!{acquire,self()}.
release(Semaphore) ->
Semaphore!release.
stop(Semaphore) ->
Semaphore!stop.
The next problem is to ensure that a semaphore can only be released
by a process
which had previously acquired it.
Oh yes, lists:append([PID], WaitList)
can be written more clearly as
[PID] ++ WaitList
and more clearly still as
[PID | WaitList].
More information about the erlang-questions
mailing list