2011-11-10 17 views
6

Tôi xin lỗi nếu mã khó theo dõi. Đây là vấn đề triết học ăn uống cổ điển, nơi 5 nhà triết học đang ăn, nhưng chỉ có 5 gậy - và bạn cần hai cái để ăn.Erlang - Các nhà triết học ăn uống lỗi

Đây là những hướng dẫn, nếu có ai quan tâm: http://www.kth.se/polopoly_fs/1.260940!/Menu/general/column-content/attachment/philosophers.pdf

Anyways, đây là mã, mã quá trình đũa:

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

Mã quá trình triết học:

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

Và cuối cùng là quy trình lưu trữ:

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

Output:

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

Cảm ơn rất nhiều nếu bạn thậm chí đọc qua tất cả những điều này, tôi đã không biết làm thế nào để đọc các báo cáo lỗi của erlang được nêu ra. Nếu bạn có thể, và muốn cho tôi biết nó có nghĩa là làm gì.

+0

Chỉ cần để bạn biết lịch sử văn bản đầy đủ của câu hỏi của bạn luôn luôn có sẵn, mặc dù bạn đã chỉnh sửa nó để không bao gồm mật mã. Tôi tin rằng bạn có tùy chọn xóa hoàn toàn bài đăng vì đó là bài đăng của bạn. – nbrooks

Trả lời

8

Tôi nghĩ vấn đề là bạn đã có ba mô-đun: dinner, eater, và chopstick, nhưng cố gắng gọi philospher:start chức năng dinner:init/0 của bạn. Thay vào đó, hãy thử dùng eater:start.

Vấn đề thứ hai là thứ tự của mô-đun và tên hàm khi tạo số ngẫu nhiên; thay thế uniform:random với random:uniform trong eater.erl của bạn:

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

này khá nhanh chóng cho thấy vấn đề thứ ba - một cái gì đó chúng ta nên đã phát hiện từ báo cáo lỗi đầu tiên - rằng ăn không thực sự trong các quá trình riêng của họ. Vì vậy, sửa eater.erl để các start() chức năng đọc:

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

Bây giờ nó hoạt động như mong đợi:

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

Cảm ơn. Đây là một điều thú vị.

+1

"Vấn đề thứ hai" từ câu trả lời của sarnold vẫn không cố định. – dsmith

+0

Tôi đã thêm nhận xét về các sự cố trong bài đăng mở, cảm ơn, nó hoạt động! – Rickard

2

thay đổi bất cứ nơi nào bạn đang gọi: uniform:random/1 -random:uniform/1 và ngoại lệ sẽ được đi

Các vấn đề liên quan