This might seem overly complicated but it works, pools your
connections/handlers/whatever and is general enough to be reused with
little change. (Don’t be scared, look at the bottom and see how easy it
is to use 
batsman@tux-chan:/tmp$ expand -t 2 c.rb
require ‘thread’
class PooledWhatever
def initialize(klass, howmany, args, debug = false)
@mutex = Mutex.new
@pool =
@handleravail = ConditionVariable.new
howmany.times { @pool << klass.new(*args) }
@threads = {}
puts “Handler pool: #{@pool.inspect}” if debug
end
def run(debug = false)
ref =
handler = nil
@mutex.synchronize do
info = false
if @pool.size == 0
@handleravail.wait @mutex
info = true if debug
end
handler = @pool.shift
puts “Got handler #{handler} after getting blocked.” if info
@threads[handler] = ref # hack cause want this
# inside synchronize; perhaps not needed
end
ref << Thread.new do
begin
yield handler
ensure
@mutex.synchronize do
@pool << handler
@threads.delete handler
@handleravail.signal
end
end
end
end
def wait_for_all
@threads.each do |handler, thread|
thread[0].join
end
@pool.each { |x| x.close }
end
def num_tasks
@threads.size
end
end
class Dummy
def close
puts “Closing handler #{self}…”
end
end
runner = PooledWhatever.new(Dummy, 4, , true)
10.times do |i|
runner.run(true) do
puts “DOING MAGIC: num threads == #{runner.num_tasks}”
sleep ( i.to_f / 20 )
end
end
runner.wait_for_all
batsman@tux-chan:/tmp$ ruby c.rb
Handler pool: [#Dummy:0x40247a20, #Dummy:0x40247a0c,
#Dummy:0x402479bc, #Dummy:0x402479a8]
DOING MAGIC: num threads == 1
DOING MAGIC: num threads == 2
DOING MAGIC: num threads == 2
DOING MAGIC: num threads == 3
DOING MAGIC: num threads == 4
Got handler #Dummy:0x40247a0c after getting blocked.
DOING MAGIC: num threads == 4
Got handler #Dummy:0x402479bc after getting blocked.
DOING MAGIC: num threads == 4
Got handler #Dummy:0x402479a8 after getting blocked.
DOING MAGIC: num threads == 4
Got handler #Dummy:0x40247a20 after getting blocked.
DOING MAGIC: num threads == 4
Got handler #Dummy:0x40247a0c after getting blocked.
DOING MAGIC: num threads == 4
Closing handler #Dummy:0x402479bc…
Closing handler #Dummy:0x402479a8…
Closing handler #Dummy:0x40247a20…
Closing handler #Dummy:0x40247a0c…
···
On Sat, Feb 01, 2003 at 08:35:24AM +0900, Daniel Bretoi wrote:
Scenario: I have a set of 20 things to do. I can only do 4 things at a
time.
How can I limit myself to 4 threads?
This is what I have:
threads =
designs.each { |d|
while threads.size > ARGV[0].to_i
do something?
end
threads << Thread.new(d) { |t|
do stuff…
}
}
how would I remove a thread once it’s done?
ideas?
–
_ _
__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_
_ \ / ` | ’ \
) | (| | |__ \ | | | | | (| | | | |
.__/ _,|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com
The only “intuitive” interface is the nipple. After that, it’s all learned.
– Bruce Ediger, bediger@teal.csn.org, on X interfaces