2011-11-10 4 views
6

Mi scuso se il codice è difficile da seguire. Questo è il classico problema dei filosofi della ristorazione, in cui 5 filosofi mangiano, ma ci sono solo 5 bastoncini - e ne avete bisogno di due da mangiare.Errori di Erlang - Dining Philosophers

Queste sono le istruzioni, se qualcuno è interessato: http://www.kth.se/polopoly_fs/1.260940!/Menu/general/column-content/attachment/philosophers.pdf

In ogni modo, ecco il codice, il codice di processo bacchette:

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

start() -> 
spawn_link(fun() -> init() end). 
init() -> 
available(). 

available() -> 
receive 
    {request, From} -> 
     From ! granted, 
     gone(); 
    quit -> 
     ok 
     end. 
gone() -> 
receive 
    returned -> 
     available(); 
    quit -> 
     ok 
     end. 

Il codice processo filosofo:

-module(eater). 
-import(timer, [sleep/1]). 
-import(random, [uniform/1]). 
-export([start/5, dream/5, eat/5, wait/5]). 

start(Hungry, Right, Left, Name, Ctrl) -> 
dream(Hungry, Right, Left, Name, Ctrl). 

**%This was wrong, it should say start(Hungry, Right, Left, Name, Ctrl) -> 
spawn_link(fun() -> dream(Hungry, Right, Left, Name, Ctrl) end).** 

dream(Hungry, Right, Left, Name, Ctrl) -> 
Time = 500+uniform:random(500), **%This was wrong, it should say random:uniform** 
timer:sleep(Time), 
Right! {request, self()}, 
Left! {request, self()}, 
%skicka {request, self()} till två pinnar 
wait(Hungry, Right, Left, Name, Ctrl). 

wait(Hungry, Right, Left, Name, Ctrl) -> 
receive 
    granted -> 
     io:format("~s received a chopstick~n", [Name]), 
     receive 
      granted -> 
      io:format("~s received a chopstick~n", [Name]), 
      io:format("~s started eating~n", [Name]), 
      eat(Hungry, Right, Left, Name, Ctrl) 
      end; 
    _ -> wait(Hungry, Right, Left, Name, Ctrl) 
end. 

eat(Hungry, Right, Left, Name, Ctrl) -> 
Time = 500+uniform:random(500), **%This was wrong, it should say random:uniform** 
timer:sleep(Time), 
Right! returned, 
Left! returned, 
io:format("~s put back two chopsticks~n", [Name]), 
if 
    Hungry =< 1 -> 
     Ctrl ! done; 
    true -> 
     dream(Hungry-1, Right, Left, Name, Ctrl) 
end.  

E infine la procedura host:

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


start() -> 
spawn(fun() -> init() end). 

init() -> 
C1 = chopstick:start(), 
C2 = chopstick:start(), 
C3 = chopstick:start(), 
C4 = chopstick:start(), 
C5 = chopstick:start(), 
Ctrl = self(), 
eater:start(5, C1, C2, "Confucios", Ctrl), **% This is where it crashes** 
eater:start(5, C2, C3, "Avicenna", Ctrl), 
eater:start(5, C3, C4, "Plato", Ctrl), 
eater:start(5, C4, C5, "Kant", Ctrl), 
eater:start(5, C5, C1, "Descartes", Ctrl), 
wait(5, [C1, C2, C3, C4, C5]). 


wait(0, Chopsticks) -> 
lists:foreach(fun(C) -> C ! quit end, Chopsticks); 
wait(N, Chopsticks) -> 
receive 
    done -> 
     wait(N-1, Chopsticks); 
    abort -> 
     erlang:exit(abort) 
end. 

uscita:

11> dinner:start(). 
<0.85.0> 
12> 
=ERROR REPORT==== 10-Nov-2011::02:19:10 === 
Error in process <0.85.0> with exit value: {undef,[{uniform,random,[500]}, {eater,dream,5},{dinner,init,0}]} 

Grazie molto se anche leggere attraverso tutto questo, non ho imparato a leggere le segnalazioni di errori di Erlang ancora. Se puoi, e vuoi dirmi cosa significa, per favore fallo.

+0

Solo così si sa la storia testo completo della tua domanda è sempre disponibile, anche se è stato modificato per non comprendere il codice. Credo che tu abbia la possibilità di cancellare completamente il post, poiché è tuo. – nbrooks

risposta

8

Credo che il problema è che hai tre moduli: dinner, eater, e chopstick, ma tenta di chiamare philospher:start nella funzione dinner:init/0. Prova invece a eater:start.

Il secondo problema è l'ordine del modulo e il nome della funzione quando si generano numeri casuali; sostituire uniform:random con random:uniform nel vostro eater.erl:

1> dinner:start(). 
<0.35.0> 
Confucios received a chopstick 
Confucios received a chopstick 
Confucios started eating 
Confucios put back two chopsticks 
Confucios received a chopstick 
Confucios received a chopstick 
Confucios started eating 
Confucios put back two chopsticks 
Confucios received a chopstick 
Confucios received a chopstick 
Confucios started eating 
Confucios put back two chopsticks 
Confucios received a chopstick 
Confucios received a chopstick 
Confucios started eating 
Confucios put back two chopsticks 
Confucios received a chopstick 
Confucios received a chopstick 
Confucios started eating 
Confucios put back two chopsticks 
Avicenna received a chopstick 
Avicenna received a chopstick 
Avicenna started eating 
... 

Questa mostra abbastanza rapidamente il terzo problema - qualcosa che avremmo dovuto individuato dalla prima segnalazione errori - che i mangiatori non sono in realtà nei loro processi. Quindi modificare eater.erl modo che la funzione start() legge:

start(Hungry, Right, Left, Name, Ctrl) -> 
    spawn_link(fun() -> dream(Hungry, Right, Left, Name, Ctrl) end). 

Ora funziona come previsto:

1> dinner:start(). 
<0.35.0> 
Confucios received a chopstick 
Plato received a chopstick 
Confucios received a chopstick 
Confucios started eating 
Descartes received a chopstick 
Kant received a chopstick 
Confucios put back two chopsticks 
Avicenna received a chopstick 
... 

Grazie. Questo è stato divertente.

+1

Il "secondo problema" dalla risposta di sarnold non è ancora risolto. – dsmith

+0

Ho aggiunto commenti sui problemi nel post di apertura, grazie, funziona! – Rickard

2

cambiamento, ovunque si sta chiamando: uniform:random/1 -random:uniform/1 e l'eccezione sarà andato