2011-11-10 10 views
6

अगर कोड का पालन करना मुश्किल है तो मैं क्षमा चाहता हूं। यह क्लासिक डाइनिंग दार्शनिक समस्या है, जहां 5 दार्शनिक खा रहे हैं, लेकिन केवल 5 छड़ें हैं - और आपको खाने के लिए दो की जरूरत है।एरलांग - डाइनिंग फिलॉसॉफर्स त्रुटियां

ये निर्देश दिए गए हैं कि अगर किसी को दिलचस्पी है: फिर भी http://www.kth.se/polopoly_fs/1.260940!/Menu/general/column-content/attachment/philosophers.pdf

, यहाँ कोड, chopstick प्रक्रिया कोड है:

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

दार्शनिक प्रक्रिया कोड:

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

और अंत में होस्ट प्रक्रिया:

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

आउटपुट:

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

धन्यवाद एक बहुत अगर आप भी इस सब के माध्यम से पढ़ा है, मुझे नहीं सीखा है कि कैसे अभी तक erlang की त्रुटि रिपोर्ट पढ़ने के लिए। यदि आप कर सकते हैं, और मुझे बताना चाहते हैं कि इसका क्या अर्थ है कृपया करें।

+0

चला जाएगा जैसा कि आप जानते अपने प्रश्न का पूरा पाठ इतिहास हमेशा उपलब्ध है, भले ही आप इसे संपादित किया है को शामिल नहीं करने के लिए कोड। मेरा मानना ​​है कि आपके पास पोस्ट को पूरी तरह से हटाने का विकल्प है, क्योंकि यह आपका है। – nbrooks

उत्तर

8

मुझे लगता है कि समस्या यह है कि आप तीन मॉड्यूल मिल गया है: dinner, eater, और chopstick, लेकिन अपने dinner:init/0 समारोह में philospher:start कॉल करने के लिए प्रयास करें। इसके बजाय eater:start आज़माएं।

यादृच्छिक संख्या उत्पन्न करते समय दूसरी समस्या मॉड्यूल और फ़ंक्शन नाम का क्रम है; अपने eater.erl में random:uniform साथ uniform:random बदल देते हैं:

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

यह सुंदर जल्दी से तीसरी समस्या से पता चलता - कुछ हम पहले त्रुटि रिपोर्ट से देखा जाना चाहिए था - कि खाने वालों की अपनी प्रक्रियाओं में वास्तव में नहीं हैं। तो eater.erl संपादित करें ताकि start() समारोह में लिखा है:

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

अब के रूप में इरादा यह काम करता है:

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

धन्यवाद। यह अच्छा मजेदार था।

+1

सरनाल्ड के उत्तर से "दूसरी समस्या" अभी भी तय नहीं है। – dsmith

+0

मैंने शुरुआती पोस्ट में समस्याओं के बारे में टिप्पणियां जोड़ दीं, धन्यवाद, यह काम करता है! – Rickard

2

परिवर्तन भी आप बुला रहे हैं: uniform:random/1 random:uniform/1 करने और अपवाद