Created
January 23, 2015 04:21
-
-
Save Incanus3/f14477117a081280ecaa to your computer and use it in GitHub Desktop.
schedule blocks to run in single thread
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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