我的生产者 - 消费者示例不起作用,但不会抛出任何错误

时间:2015-10-04 12:40:16

标签: ruby

意图

每个用户都有很多专辑;每张专辑都有很多图片。该类使用用户名进行实例化,并将下载其中的每个图像。图像表示为带有:url:title:index键的哈希(索引表示相册中的图片#1,#2,#3等)。

制作人将获得所有专辑的列表,打开专辑#1,将所有图像推入队列,打开专辑#2,将所有图像推送到队列等。同时消费者查看队列,下载图像,再次查看队列等。

在工作结束时,生产者将符号:KILL添加到队列中。消费者在每个pop上检查此符号,如果它看到它,则退出。

描述了该对象:

  • @queue = Queue.new
  • @username:字符串
  • @threads:包含五个主题,一个生产者和四个消费者的数组
  • #download:将图像对象保存到用户文件夹中的文件
  • #albums_of_user:不执行任何操作,返回一组哈希值,每个哈希值代表一个属于该用户的相册,其中包含:url:title属性
  • #images_in_album:获取上述专辑哈希值之一,返回代表相册中图片的哈希数组,准备传递给#download
  • #consumer#producer:返回新的消费者或生产者线程

initialize调用结束时,调用@threads.map(&:join),以确保所有线程完成其工作。

生产者

Thread.new {
  albums_of_user.each do |album|
    images_in_album(album).each.with_index(1) do |image, index|
      @queue << image
    end
  end
  @queue << :KILL
}

消费者

Thread.new {
  loop do
    image = @queue.pop
    Thread.exit if image == :KILL
    download(image)
  end
}

问题

制作人工作,下载功能有效,但消费者从不做任何事情。如果有人能指出我搞砸了哪里,我会很高兴。

代码

http://pastebin.ca/3180196

1 个答案:

答案 0 :(得分:0)

您确定消费者没有做任何事情吗?你只是推动一个:KILL进入队列,所以只有一个消费者线程被杀死,导致程序永无止境或错误。由于缓冲区缓存,您可能无法获得任何打印输出,因此您可能需要$ stdout.flush,因为您要杀死该线程。

有关示例,请参阅http://pastebin.ca/3180306。 (注意:这删除了实际的下载,因为我希望它能够快速运行:o)