Created
March 14, 2012 15:05
-
-
Save rkh/2037092 to your computer and use it in GitHub Desktop.
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' | |
| 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 |
Author
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.
Author
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.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If you have more than one worker, only one of them will shutdown, as the
@closingwill only be set once. You probably need to remember your worker threads and schedulecloseon each of them directly (or at least schedulecloseworker_threads.counttimes.