Ruby and Threading Fun

August 9, 2008

So here is a class I wrote in ruby.

class LimitedThreads
    def initialize max
        @group = ThreadGroup.new
        @maxthreads = max
        @lock = Mutex.new
        @slot = ConditionVariable.new
    end

    def to_s
        "max threads: %s; current threads: %s;" % [@maxthreads, @group.list.size]
    end

    def newthread *args
        if @maxthreads <= @group.list.size
            #delay until a thread ends
            @lock.synchronize { @slot.wait(@lock) }
        end
        nt = Thread.new do
            yield *args #this allows operation like Thread.new for passing in args to thread
            @lock.synchronize { @slot.signal }
        end
        @group.add nt
        nt
    end
end

You create an object from this with the maximum amount of threads you want it to allow to run at any given time. You use LimitedThreads#newthread with a block representing the thread you want to run. If the instance has a spot free for that thread, it will run it. Otherwise, it will wait until a already running thread finishes to start up the new thread. Now, this code probably has no real use, but it was an interesting exercise for me. Ruby is interesting in that it uses blocks for threads, not methods. The comment inside the Thread.new call is on the subject of passing arguments into the block that LimitedThreads#newthread takes. Anyway, here is an example of how to use it.

lt=LimitedThreads.new 3
sleep_time = 2
12.times do |count|
    message = "hello from pass number %s" % count
    lt.newthread(message, sleep_time) do |msg, st|
        sleep st
        puts msg
    end
end

On my system, this consistently prints:

hello from pass number 1
hello from pass number 0
hello from pass number 2
hello from pass number 4
hello from pass number 3
hello from pass number 5
hello from pass number 7
hello from pass number 6
hello from pass number 8

Printing each group of three at 2 second interval bursts (all in group appear). Try it on other systems; it might do something else. If you can find a use for it, please, tell me.


Ruby.

July 7, 2008

I taught myself Ruby a couple of weeks ago, and I’ve been working on a project based on Ruby on Rails. I guess I’ve had enough time to think about it to coherently describe what I think of it.

  • Overall, Ruby is a good language, and I’m glad I learned it.
  • I’ve known Python for a while, and both Python and Ruby allow some very strange things to be done: Python allows me to attach anything to an object, even functions, and Ruby lets me reopen a class at any point. Fine.
  • There are certain subtle differences between Ruby and Python that I have to get over. Case in point: in Python, any python file is automatically a separate module. In Ruby, a Module can occur over several files, but loading a file brings all of its stuff into the same name space. This tripped me up at first.
    I really like blocks. They are cool.
  • Ruby on Rails is useful, and ActiveRecord made my life much easier in working on the previously mentioned project.
  • Maybe my thoughts on this are not so coherent.