我前開始關於Ruby不到一週的時間,但是已經走到 欣賞語言的力量。我想在一個經典的 生產者消費者問題我的手,爲橙樹(C.F. http://pine.fm/LearnToProgram/?Chapter=09)來實現。橙樹生長的每個 年,直到它死了,產生橙子每年 (監製)的隨機數。只要樹上有任何東西(消費者),就可以挑選橘子。紅寶石多線程的生產者 - 消費者
我有兩個問題在這裏:
下面的代碼給我下面的異常(無法連接,沒有選項):
/Users/Abhijit/Workspace/eclipse/ruby/learn_to_program/orange_tree.rb:84: warning: instance variable @orange_tree not initialized /Users/Abhijit/Workspace/eclipse/ruby/learn_to_program/orange_tree.rb:84:in `': undefined method `age' for nil:NilClass (NoMethodError) from /Users/Abhijit/Workspace/eclipse/ruby/learn_to_program/orange_tree.rb:45:in `'
我不知道多線程部分被正確編碼。
我有幾本書,包括「編程Ruby」和「Ruby編程語言」,但都沒有包含真正的「生產者 - 消費者問題」。
P.S:對於充分披露的緣故,我也張貼在論壇上的Ruby這個問題。不過,我已經看到了很好的答案和/或在這裏提供的建議,並希望我也能得到一些。
require 'thread'
class OrangeTree
GROWTH_PER_YEAR = 1
AGE_TO_START_PRODUCING_ORANGE = 3
AGE_TO_DIE = 7
ORANGE_COUNT_RELATIVE_TO_AGE = 50
def initialize
@height = 0
@age = 0
@orange_count = 0
end
def height
return @height
end
def age
return @age
end
def count_the_oranges
return @orange_count
end
def one_year_passes
@age += 1
@height += GROWTH_PER_YEAR
@orange_count = Math.rand(@age..AGE_TO_DIE) * Math.log(@age) * ORANGE_COUNT_RELATIVE_TO_AGE
end
def pick_an_orange
if (@age == AGE_TO_DIE)
puts "Sorry, the Orange tree is dead"
elsif (@orange_count > 0)
@orange_count -= 1
puts "The Orange is delicious"
else
puts "Sorry, no Oranges to pick"
end
end
end
class Worker
def initialize(mutex, cv, orange_tree)
@mutex = mutex
@cv = cv
@orange_tree = orange_tree
end
def do_some_work
Thread.new do
until (@orange_tree.age == OrangeTree.AGE_TO_DIE)
@mutex.synchronize do
sleep_time = rand(0..5)
puts "Orange picker going to sleep for #{sleep_time}"
sleep(sleep_time)
puts "Orange picker woke up after sleeping for #{sleep_time}"
@orange_tree.pick_an_orange
puts "Orange picker waiting patiently..."
@cv.wait(@mutex)
end
end
end
Thread.new do
until (@orange_tree.age == OrangeTree.AGE_TO_DIE)
@mutex.synchronize do
sleep_time = rand(0..5)
puts "Age increaser going to sleep for #{sleep_time}"
sleep(sleep_time)
puts "Age increaser woke up after sleeping for #{sleep_time}"
@orange_tree.one_year_passes
puts "Age increaser increased the age"
@cv.signal
end
end
end
end
Worker.new(Mutex.new, ConditionVariable.new, OrangeTree.new).do_some_work
until (@orange_tree.age == OrangeTree.AGE_TO_DIE)
# wait for the Threads to finish
end
end
讓你建議的修改,包括加入後,現在我得到: 橙色選擇器臨睡前睡覺的5 對不起後5 橙色拾取醒來,沒有橘子挑 橙色選擇器耐心等待... 年齡增速臨睡前2 年齡增速睡了2 012睡醒後/Users/Abhijit/Workspace/eclipse/ruby/learn_to_program/orange_tree.rb:76:in'join':檢測到死鎖(致命) \t from /Users/Abhijit/Workspace/eclipse/ruby/learn_to_program/orange_tree.rb: 76:在'do_some_work' \t from ... – 2013-02-14 12:25:30
那是在第二個'join'嗎?它看起來像上面的例子嗎? – bioneuralnet 2013-02-14 16:07:07
下面是一些代碼片段(希望我能知道如何對其進行格式化) 結束 orange_picker.join age_increaser.join 結束 工人= Worker.new(Mutex.new,ConditionVariable.new,OrangeTree.new) 工人.do_some_work end – 2013-02-14 16:47:16