S
Sam Dalton
I'm relatively new to Ruby, having switched from a PHP and Java
background, and I'm having some trouble with the Monitor class trying to
implement a synchronised circular buffer. The other posts here on
synchronised methods aren't quite relevant enough unfortunately.
My current implementation is the following
require 'monitor'
class SynchronisedBuffer < Monitor
def initialize(capacity)
@capacity = capacity
@front = 0
@back = 0
@elements = Array.new(capacity)
@empty_cond = new_cond
@full_cond = new_cond
super()
end
def get
@empty_cond.wait_while {empty?}
element = nil
synchronize do
element = @elements[@front]
@elements[@front] = nil
@front = (@front + 1) % @capacity
@full_cond.signal
end
return element
end
def put(element)
@full_cond.wait_while {full?}
synchronize do
@elements[@back] = element
@back = (@back + 1) % @capacity
@empty_cond.signal
end
end
def full?
result = false
synchronize do
result = (@front == @back and @elements[@front] != nil)
end
return result
end
def empty?
result = false
synchronize do
result = (@front == @back and @elements[@front] == nil)
end
return result
end
end
This has been adapted from a version I had written in Java. The problem
is that when I have a thread call 'get' on the buffer, I receive a
ThreadException saying 'current thread not owner'
This is being thrown by mon_check_owner, and a bit of poking around
shows that it fails because mon_owner is set to nil in the condition
'@mon_owner != Thread.current'.
I am using the buffer for a simple producer/consumer web server, like so
buffer = SynchronisedBuffer.new(10)
workers = []
for i in (1..10)
workers = Worker.new(buffer)
end
while socket = server.accept
buffer.put(socket)
end
I'm writing this purely to gain a better understanding of some important
ruby classes like thread, monitor and socket, and am aware that there
are other ruby web servers I could use straight away
. I'm also trying
to understand the 'ruby way' of coding, so any comments as to how the
above code might better be written would be really appreciated.
Sam Dalton
background, and I'm having some trouble with the Monitor class trying to
implement a synchronised circular buffer. The other posts here on
synchronised methods aren't quite relevant enough unfortunately.
My current implementation is the following
require 'monitor'
class SynchronisedBuffer < Monitor
def initialize(capacity)
@capacity = capacity
@front = 0
@back = 0
@elements = Array.new(capacity)
@empty_cond = new_cond
@full_cond = new_cond
super()
end
def get
@empty_cond.wait_while {empty?}
element = nil
synchronize do
element = @elements[@front]
@elements[@front] = nil
@front = (@front + 1) % @capacity
@full_cond.signal
end
return element
end
def put(element)
@full_cond.wait_while {full?}
synchronize do
@elements[@back] = element
@back = (@back + 1) % @capacity
@empty_cond.signal
end
end
def full?
result = false
synchronize do
result = (@front == @back and @elements[@front] != nil)
end
return result
end
def empty?
result = false
synchronize do
result = (@front == @back and @elements[@front] == nil)
end
return result
end
end
This has been adapted from a version I had written in Java. The problem
is that when I have a thread call 'get' on the buffer, I receive a
ThreadException saying 'current thread not owner'
This is being thrown by mon_check_owner, and a bit of poking around
shows that it fails because mon_owner is set to nil in the condition
'@mon_owner != Thread.current'.
I am using the buffer for a simple producer/consumer web server, like so
buffer = SynchronisedBuffer.new(10)
workers = []
for i in (1..10)
workers = Worker.new(buffer)
end
while socket = server.accept
buffer.put(socket)
end
I'm writing this purely to gain a better understanding of some important
ruby classes like thread, monitor and socket, and am aware that there
are other ruby web servers I could use straight away
to understand the 'ruby way' of coding, so any comments as to how the
above code might better be written would be really appreciated.
Sam Dalton