Classical concurrent problems

Mark Wutka <>
Sat Feb 11 02:08:42 CET 2006


" " Hi,
" " 
" " Where can I find erlang solutions to classical concurrent problems such as
" " the dinning philosophers? I tried googling but didn't find anything
" " 
" " Thanks
" " 
" 
" I did a version of it in Erlang, I just can't vouch for it being *good*
" Erlang. It isn't too long, so I think it's probably okay to just stick
" it in the message. The each chopstick and philosopher is a process. The
" philosophers strategy is just to pick up the left chopstick, then try
" the right. If it can't get the right, it drops the left, waits, and
" tries again. You can experiment with other strategies, of course.
" I put a wait_for function in chopstick to wait for a chopstick, but the
" current philosopher implementation doesn't use it.
"   Mark

I discovered a few things about my previous program. First, Sam
Montgomery-Blinn was kind enough to point out the extraneous semicolon
in chopstick.erl. Second, the random number generator appears to keep
separate per-process seeds. When the 5 philosophers start up, they all
start with identical seeds. I tried seeding with the time, but they all
started up so fast, they still had the same seed. I modified dining.erl
to compute random seeds for each philosopher. The philosopher process
then initializes the random number generator at startup. Here is the
updated dining.erl:

-module(dining).
-export([start/0]).

start() ->
    %% Start the random number generator

    %% Create the chopsticks
    C1 = chopstick:start(),
    C2 = chopstick:start(),
    C3 = chopstick:start(),
    C4 = chopstick:start(),
    C5 = chopstick:start(),

    %% Start the philosophers each with a different pair of chopsticks
    philosopher:start(C1, C2, "Lao Tzu", randomize()),
    philosopher:start(C2, C3, "Plato", randomize()),
    philosopher:start(C3, C4, "Socrates", randomize()),
    philosopher:start(C4, C5, "Descartes", randomize()),
    philosopher:start(C5, C1, "Hume", randomize()).

randomize() ->
    { random:uniform(100000),
      random:uniform(100000),
      random:uniform(100000) }.

They I just modified the beginning of philosopher.erl:

-module(philosopher).
-export([start/4, init/4]).
-define(MaxThink, 10000).
-define(MaxEat, 10000).
-define(MaxWait, 1000).

start(Left, Right, Name, RandSeed) ->
    spawn(philosopher, init, [Left, Right, Name, RandSeed]).

init(Left, Right, Name, RandSeed) ->
    {A1, A2, A3} = RandSeed,
    random:seed(A1, A2, A3),
    think(Left, Right, Name).

.
.
.

Now the processes seem much more spread out and there seemd to be less
contention.
  Mark



More information about the erlang-questions mailing list