我前开始关于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