« Back to Index

Ruby Data Structures: Queue

View original Gist on GitHub

Ruby Queue.md

Another useful data structure is Queue. This is a synchronised, i.e. thread safe, first-in first-out queue. This makes it easy to coordinate work between threads.

Below is a simple example of a program that lets you enter multiple URLs to download, then works through them one by one in the background:

require "thread" # Queue is part of the thread library
require "net/http"

to_do = Queue.new

Thread.abort_on_exception = true # if one thread dies, everyone dies

interface = Thread.new do
  loop do
    url = STDIN.gets # waits here until a URL has been entered
    if url && url != "quit\n"
      to_do.push(URI.parse(url))
    else
      to_do.push(false)
      break
    end
  end
end

fetcher = Thread.new do
  loop do
    uri = to_do.pop # waits until there's a URI in the queue
    break unless uri
    result = Net::HTTP.get(uri)
    File.open("#{uri.host}#{uri.path.tr("/", ":")}", "w+") do |f|
      f << result
    end
    puts "downloaded #{uri}"
  end
end

[interface, fetcher].each(&:join) # don't exit until the threads are done