Skip to content

Instantly share code, notes, and snippets.

@Incanus3
Created January 23, 2015 04:21
Show Gist options
  • Save Incanus3/f14477117a081280ecaa to your computer and use it in GitHub Desktop.
Save Incanus3/f14477117a081280ecaa to your computer and use it in GitHub Desktop.
schedule blocks to run in single thread
require 'thread'
# input_queue = Queue.new
# computer = Thread.new do
# loop do
# x, y, block, output_queue = input_queue.pop
# puts "computing #{x} + #{y}"
# sleep 1
# puts "calling block"
# block.call
# output_queue << x + y
# end
# end
# 3.times do |i|
# result_queue = Queue.new
# input_queue << [i, 10 - i, proc { puts i }, result_queue]
# puts "waiting for result"
# puts "result: #{result_queue.pop}"
# end
class NeoThread
# all calls execute the block in the one looping thread (using input queue)
# calls are blocking (thanks to ouptut_queue.pop)
# to make them non-blocking, output queue could just be returned (as a
# promise) and caller would then call pop on it when needed
def self.execute(&block)
output_queue = Queue.new
input_queue << [block, output_queue]
output_queue.pop
end
def self.start
return if @started
@started = true
@thread = Thread.new do
loop do
block, output_queue = input_queue.pop
result = block.call
output_queue << result
end
end
end
def self.stop
@thread.stop if @thread
end
private
def self.input_queue
@input_queue ||= Queue.new
end
end
puts "main thread: #{Thread.current}"
NeoThread.start
NeoThread.execute { puts "main scheduled for neo thread (#{Thread.current})"; sleep 1 }
threads = Array.new(3) do |i|
Thread.new do
puts "worker: #{i}, thread: #{Thread.current}"
NeoThread.execute do
puts "#{i} scheduled for neo thread (#{Thread.current})"
sleep 1
end
puts "end worker: #{i}"
end
end
threads.each(&:join)
puts "end main thread"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment