每个用户都有很多专辑;每张专辑都有很多图片。该类使用用户名进行实例化,并将下载其中的每个图像。图像表示为带有: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
}
制作人工作,下载功能有效,但消费者从不做任何事情。如果有人能指出我搞砸了哪里,我会很高兴。
答案 0 :(得分:0)
您确定消费者没有做任何事情吗?你只是推动一个:KILL进入队列,所以只有一个消费者线程被杀死,导致程序永无止境或错误。由于缓冲区缓存,您可能无法获得任何打印输出,因此您可能需要$ stdout.flush,因为您要杀死该线程。
有关示例,请参阅http://pastebin.ca/3180306。 (注意:这删除了实际的下载,因为我希望它能够快速运行:o)