I followed up and it seems that you're right, I had assumed the recv
was blocking the whole process but it was not. Based on what I've seen
after some further testing it seems that 'Kernel#gets' and
'Socket#connect' can both block the process. Is this correct?
Here's another test using TCPSocket that works just fine as you
suggested. If you comment out the lines at the bottom where I would
try to read from the console it freezes the application.
Opening multiple telnet sessions to localhost:5000 shows multiple
connection threads operating in parallel.
require 'socket'
def handle_session(sess)
puts "accepted session from #{sess}"
sclient = Thread.new {
while(1)
data, cli = sess.recv(256)
puts "Server got #{data} from #{sess}"
end
}
end
server = Thread.new {
s = TCPServer.new(nil, 5000)
while(true)
puts "ready to accept next session..."
sess = s.accept
handle_session(sess)
end
}
client = Thread.new {
s = TCPSocket.open('localhost', 5000)
puts "client connected..."
while(true)
puts "sending hello"
s.send("hello", 0)
sleep 1
end
}
sleep
#while(true)
#line = gets
#puts line
#end
On 2/18/06, Joel VanderWerf <vjoel / path.berkeley.edu> wrote:
> Jacob Repp wrote:
> > It's not that simple. For example:
> >
> > # server
> > server = Thread.new {
> > s = UDPSocket.open
> > s.bind(nil, 5000)
> > while(true)
> > data, cli = s.recvfrom(256)
> > puts "Server got #{data} from #{cli}"
> > Thread.pass
> > end
> > }
> > client = Thread.new {
> > s = UDPSocket.open
> > s.connect('localhost', 5000)
> > while(true)
> > s.send("hello", 0)
> > Thread.pass
> > end
> > }
> >
> > The problem occurs on the first call that the sever thread makes to
> > recvfrom(). This is a blocking call and since ruby is actually a
> > single threaded process (with virtual soft threads) this hangs all of
> > the other virtual threads. So for my test app which is trying to run a
> > simulation thread as well as handle socket and console IO this becomes
> > a problem quickly.
>
> That code works fine for me, using ruby-1.8.4, both linux and windows
> (the one-click msvc-built version).
>
> Also, the Thread.pass is not needed.
>
> I did add a line at the end:
>
> sleep
>
> (You could also use Thread.join(client) or similar.)
>
> --
> vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
>
>