Random in Erlang

By: on September 6, 2006

I was recently trying to fix our Erlang Jukebox (which Tony is still owing a Blog Post for (and once he’s done that I can write a blog post on adding m3u support to our Erlang Jukebox (and some time after that it should be opensourced…))) so that it would randomly enqueue the wrong track, just to spice things up. Erlang has a `uniform` function in the `random` module which returns a float uniformly distributed between 0 and 1. “Brilliant” said I.

However, the `random` module stores its state in the process dictionary which means that each process has a different state for the `random` module. It also seems to get seeded by preset values rather than by some more suitable time-based value. So, all works well within the same process:

> lists:foreach(fun(E) -> io:format(“~w~n”, [random:uniform()]) end,
lists:seq(1,10)).
0.289971
0.186964
0.640637
0.553759
0.478947
0.457143
0.920461
0.915298
0.968977
0.903338
ok

But, once all the call to `uniform` happens fresh in each process, things are a little less ideally random:

> lists:foreach(fun(E) -> F = fun() ->
io:format(“~w~n”, [random:uniform()]) end,
spawn(F) end,
lists:seq(1,10)).
9.23009e-2
9.23009e-2
9.23009e-2
9.23009e-2
9.23009e-2
9.23009e-2
9.23009e-2
9.23009e-2
9.23009e-2
9.23009e-2
ok

And of course, in our Erlang Jukebox (yes, the same one Tony’s due to blog about), using the Erlang webserver [Yaws](http://yaws.hyber.org/), one process is spawned per HTTP request. So I needed to seed the `random` module with a time based value to make sure that overall, the behaviour was, well, random.

Share

2 Comments

  1. Another solution could be to start a single process which gets asked for the next random number. I guess this is a bit slower, but looks very Erlangy. 🙂

    http://www.no-spoon.de/articles/2006/09/13/random-in-erlang-processes

  2. Bruce says:

    Ooohh I don’t like sites that lose my comments on “invalid security code” (and it wasn’t, dammit).

    random:seed(A1, A2, A3) -> ran() is what you’re wanting, although personally I’d have a gen_server running that held all the other state you’re lugging around. Supervisor heirarchies are the shizzle.

    erlang:now() is a convenient source of the seed inputs 🙂

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*