[erlang-questions] Counters
Richard A. O'Keefe
ok@REDACTED
Tue Apr 26 05:53:38 CEST 2016
On 25/04/16 10:36 AM, Donald Steven wrote:
> With the archived help provided by Alpar Juttner and Witold Baryluk, I
> thought I would share (primarily for other newbees like me), one way
> to implement counters.
>
> Best,
>
> Don
>
> ===================================================================================
>
>
> %%%--------------------------------------------------------------------------
>
> %%% File : counter.erl, version 1.00
> %%% Author : Donald Steven <impartialmusic@REDACTED>, adapted from
> code
> %%% suggested by Alpar Juttner and Witold Baryluk of the
> Erlang
> %%% community
> %%% Purpose : To demonstrate multiple independent counters
> %%% Created : 24 Apr 2016
> %%% Invocation : erlc counter.erl
> %%% erl -noshell -s counter main -s init stop
> %%%--------------------------------------------------------------------------
>
>
> -module(counter).
> -export([main/0,inc/1,dec/1,current/1,start/1,loop/1]).
>
> %%%--------------------------------------------------------------------------
>
> %%% Fun : inc(X), dec(X), current(X)
> %%% Purpose : Increment, decrement the counter X, and provide its current
> %%% state
> %%% Created : 24 Apr 2016
> %%%--------------------------------------------------------------------------
>
>
> inc(X) ->
> list_to_atom("counter_" ++ [X]) ! inc_counter,
> ok.
NO! DANGER, WILL ROBINSON!
Atoms are held in a fixed size table and are not garbage collected.
Constructing new atoms at run time is generally a bad idea.
That was the first thing I thought of when I saw this, but it's
actually not the worst problem. The only values of X that make
list_to_atom("counter_" ++ [X]) legal are the integers 0 to 255
inclusive. That is, a counter name X *must* be an integer 0 to 255
AND YOU HAVE NOT DOCUMENTED THIS.
Your module should NOT be registering counters.
There should simply be functions
new_counter() ->
new_counter(0).
new_counter(N) ->
spawn(fun () -> loop(N) end).
and the *CALLER* can register a counter if there is a reason to.
It's not just that doing it that way removes an arbitrary limitation,
it's that as things stand, a malicious program can easily destroy all
the counters. *And* it avoids the problem where two processes
both try to start counter 5. I have used two programming languages
(Fortran and IMP) in which I/O channels were referred to by number
and it was seriously painful trying to combine libraries that assumed
they had sole control of channel N.
By the way, I didn't see anything to *terminate* a counter.
More information about the erlang-questions
mailing list