-
-
Save rkh/2037092 to your computer and use it in GitHub Desktop.
| require 'thread' | |
| class Worker | |
| def initialize(count = 1) | |
| @queue, @closing, @threads, @mutex = Queue.new, false, [], Mutex.new | |
| add_worker(count) | |
| end | |
| def add_worker(count = 1) | |
| @mutex.synchronize do | |
| @threads += count.times.map { Thread.new { @queue.pop.call until @closing } } | |
| end | |
| end | |
| def run(block = Proc.new) | |
| @queue << block | |
| end | |
| def close(&block) | |
| run do | |
| @closing = true | |
| yield if block_given? | |
| wakeup | |
| end | |
| end | |
| def join | |
| @threads.each(&:join) | |
| end | |
| private | |
| def wakeup | |
| run { wakeup if @queue.num_waiting > 0 } | |
| end | |
| end |
Exactly what are you using this for?
@ryanlecompte check out the dummy addition I made.
@judofyr just nonsens scripts atm
@judofyr just nonsens scripts atm
Wouldn't it be better to do something like this to make sure the block is called?
def close
run do
@closing = true
yield if block_given?
end
endright
If you have more than one worker, only one of them will shutdown, as the @closing will only be set once. You probably need to remember your worker threads and schedule close on each of them directly (or at least schedule close worker_threads.count times.
No, @closing is local to the worker instance which can launch more than one thread, but it will be true in all threads.
Meh, of course... But then I wouldn't call @queue.clear to have something like a soft-stop and to not lose already scheduled jobs.
But that rather depends on your use case.
I have an old piece of code that looks awfully similar to this, but uses throw/catch instead of the @closing thing: http://burgestrand.se/code/ruby-thread-pool/thread-pool.rb (I partly did it as an experiment with rocco)
It does not support adding more workers, however.
right