2011-11-10 8 views
6

Pido disculpas si el código es difícil de seguir. Este es el clásico problema de los filósofos culinarios, donde 5 filósofos están comiendo, pero solo hay 5 palitos, y uno necesita dos para comer.Erlang - Comedor Filósofos errores

Estas son las instrucciones, si alguien está interesado: http://www.kth.se/polopoly_fs/1.260940!/Menu/general/column-content/attachment/philosophers.pdf

De todas formas, aquí está el código, el código de proceso palillo:

-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. 

El código de proceso filósofo:

-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.  

Y, finalmente, el proceso de 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. 

Salida:

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}]} 

Gracias mucho si incluso leer a través de todo esto, que no han aprendido a leer los informes de errores de Erlang todavía. Si puedes, y quieres decirme qué significa, hazlo.

+0

Para que sepan la historia texto completo de su pregunta siempre está disponible, a pesar de que usted ha editado para que no incluya el código. Creo que tienes la opción de eliminar por completo la publicación, ya que es tuya. – nbrooks

Respuesta

8

Creo que el problema es que usted tiene tres módulos: dinner, eater y chopstick, pero intenta llamar philospher:start en su función dinner:init/0. Pruebe eater:start en su lugar.

El segundo problema es el orden del módulo y el nombre de la función cuando se generan números aleatorios; uniform:random reemplazar con random:uniform en su 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 
... 

Esta muestra con bastante rapidez el tercer problema - algo que deberíamos haber visto desde el primer informe de error - que los comedores no son en realidad en sus propios procesos. Así editar eater.erl modo que la función start() lee:

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

Ahora funciona según lo 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 
... 

Gracias. Esto fue muy divertido.

+1

El "segundo problema" de la respuesta de Sarnold aún no está solucionado. – dsmith

+0

Agregué comentarios sobre los problemas en el primer post, ¡gracias, funciona! – Rickard

2

cambio donde usted está llamando: uniform:random/1 a random:uniform/1 y la excepción se ha ido