I am interested in knowing what would be the best way to implement a thread based queue.
For example:
I have 10 actions which I want to execute with only 4 threads. I would like to create a queue with all the 10 actions placed linearly and start the first 4 action with 4 threads, once one of the thread is done executing, the next one will start etc - So at a time, the number of thread is either 4 or less than 4.
Executable descriptive example:
You could use a thread pool. It's a fairly common pattern for this type of problem.
http://en.wikipedia.org/wiki/Thread_pool_pattern
Github seems to have a few implementations you could try out:
https://github.com/search?type=Everything&language=Ruby&q=thread+pool
There is a
Queue
class inthread
in the standard library. Using that you can do something like this:The reason I pop with the non-blocking flag is that between the
until queue.empty?
and the pop another thread may have pop'ed the queue, so unless the non-blocking flag is set we could get stuck at that line forever.If you're using MRI, the default Ruby interpreter, bear in mind that threads will not be absolutely concurrent. If your work is CPU bound you may just as well run single threaded. If you have some operation that blocks on IO you may get some parallelism, but YMMV. Alternatively, you can use an interpreter that allows full concurrency, such as jRuby or Rubinius.
Celluloid have a worker pool example that does this.
There area a few gems that implement this pattern for you; parallel, peach,and mine is called
threach
(orjruby_threach
under jruby). It's a drop-in replacement for #each but allows you to specify how many threads to run with, using a SizedQueue underneath to keep things from spiraling out of control.So...
Not pushing my own stuff; there are plenty of good implementations out there to make things easier.
If you're using JRuby,
jruby_threach
is a much better implementation -- Java just offers a much richer set of threading primatives and data structures to use.I use a gem called work_queue. Its really practic.
Example: