[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: Digest Articles 181864-182030 (17/17) (ruby-talk ML

benjohn

3/1/2006 11:52:00 PM


> I'm somewhat new to Ruby and have been playing around with some
> very simple
> socket code (starting the script and then telnetting to the box on
> the port
> specified). I wanted to allow it to accept more than one request at
> a time
> so I added some threads. However, now that I've added some thread
> code, I
> can't get the script to end properly (I guess "as expected" is more
> appropriate). Here's some code:

Ok, before I talk about your code, you may like to know that you
don't actually need to use threads to handle multiple sockets at
once. There is a method in the kernel called "select" that can be
used thus:

require 'socket'

server = TCPServer.new(5000)
sockets = []

while( server )
# Wait for read events on the server or sockets.
socketsWithEvents = select( [server] + sockets )[0]

# Process each socket that has an event.
socketsWithEvents.each do |soc|
if soc == server
sockets << soc.accept
else
# Close the socket if the other end has closed.
if soc.eof?
soc.close
sockets.delete(soc)
break
end

s = soc.gets.chomp
soc.puts "You said \"#{s}\", you land lubber!"
server=nil if s=="close"
end
end
end


You should be able to begin as many concurrent telnet sessions to
port 5000 as you wish, and anything typed on any will be pirated back
at.

... Perhaps other more knowledgeable Ruby users could comment on the
advantages or disadvantages of using threads or avoiding them.

As a top tip, I'd heartily recommend (if you don't already) playing
about with "irb", and trying out sockets "hands on". It's brilliant
to be able to write TCPServer.new(5000).accept, and wait for it to
return a new connection :)

>
> require 'socket'
> p = 3333
> threads = []
> s = ''
>
> server = TCPServer.new('0.0.0.0', p)
>
> while (session = server.accept)
> threads << Thread.new(session) do |ts|
> ts.print "What's your name?\r\n"
> puts "Request: #{s = ts.gets.chomp!}"
> ts.print "\r\nHello #{s}, thanks for stopping by\r\n\r\n"
> ts.close
> end
> break if s == 'close'
> end

I've just read someone else's reply mentioning that you have a "race
condition". What's happening is that when you create the thread,
you've got two lines of execution that are "racing" along through
your code, and you can never really know which one is going to be in
the lead ay any moment...

Thread.new builds a new thread that runs the block you passed in.
This thread is handling the newly created socket.

The original thread instantly returns from the Thread.new, and starts
processing just after the block on the line "break if s == 'close'".

If you're not familiar with threads, it's almost as if you've
suddenly got two processors instead of one - both of them are dashing
through your code executing statements happily, which is why careless
thread programming can cause merry havoc :)

Generally, you can't make guarantees about the speed that the two
threads will progress through the code they're assigned to. One may
go slowly for a while, and then very fast. If you need one thread to
hang back (the main thread, in this case) while the other does
something (the socket's thread does the read and sets the variable
"s"), then you _must_ use synchronisation mechanisms (Look up
"monitors" for starters).

In your case, the original thread will (usually) evaluate the "break
if..." line almost instantly, long before the new thread even gets a
chance to write to the thread, let alone read from it in to "s". When
the original thread checks "s", it wont have been updated to by the
newly spawned thread, so you wont execute the conditional break
(until the next time through the loop).

HTH, cheers (and have fun :)
Benjohn


4 Answers

benjohn

3/2/2006 7:22:00 AM

0

> I'm somewhat new to Ruby and have been playing around with some
> very simple
> socket code (starting the script and then telnetting to the box on
> the port
> specified). I wanted to allow it to accept more than one request at
> a time
> so I added some threads. However, now that I've added some thread
> code, I
> can't get the script to end properly (I guess "as expected" is more
> appropriate). Here's some code:

Ok, before I talk about your code, you may like to know that you
don't actually need to use threads to handle multiple sockets at
once. There is a method in the kernel called "select" that can be
used thus:

require 'socket'

server = TCPServer.new(5000)
sockets = []

while( server )
# Wait for read events on the server or sockets.
socketsWithEvents = select( [server] + sockets )[0]

# Process each socket that has an event.
socketsWithEvents.each do |soc|
if soc == server
sockets << soc.accept
else
# Close the socket if the other end has closed.
if soc.eof?
soc.close
sockets.delete(soc)
break
end

s = soc.gets.chomp
soc.puts "You said \"#{s}\", you land lubber!"
server=nil if s=="close"
end
end
end


You should be able to begin as many concurrent telnet sessions to
port 5000 as you wish, and anything typed on any will be pirated back
at.

... Perhaps other more knowledgeable Ruby users could comment on the
advantages or disadvantages of using threads or avoiding them.

As a top tip, I'd heartily recommend (if you don't already) playing
about with "irb", and trying out sockets "hands on". It's brilliant
to be able to write TCPServer.new(5000).accept, and wait for it to
return a new connection :)

>
> require 'socket'
> p = 3333
> threads = []
> s = ''
>
> server = TCPServer.new('0.0.0.0', p)
>
> while (session = server.accept)
> threads << Thread.new(session) do |ts|
> ts.print "What's your name?\r\n"
> puts "Request: #{s = ts.gets.chomp!}"
> ts.print "\r\nHello #{s}, thanks for stopping by\r\n\r\n"
> ts.close
> end
> break if s == 'close'
> end

I've just read someone else's reply mentioning that you have a "race
condition". What's happening is that when you create the thread,
you've got two lines of execution that are "racing" along through
your code, and you can never really know which one is going to be in
the lead ay any moment...

Thread.new builds a new thread that runs the block you passed in.
This thread is handling the newly created socket.

The original thread instantly returns from the Thread.new, and starts
processing just after the block on the line "break if s == 'close'".

If you're not familiar with threads, it's almost as if you've
suddenly got two processors instead of one - both of them are dashing
through your code executing statements happily, which is why careless
thread programming can cause merry havoc :)

Generally, you can't make guarantees about the speed that the two
threads will progress through the code they're assigned to. One may
go slowly for a while, and then very fast. If you need one thread to
hang back (the main thread, in this case) while the other does
something (the socket's thread does the read and sets the variable
"s"), then you _must_ use synchronisation mechanisms (Look up
"monitors" for starters).

In your case, the original thread will (usually) evaluate the "break
if..." line almost instantly, long before the new thread even gets a
chance to write to the thread, let alone read from it in to "s". When
the original thread checks "s", it wont have been updated to by the
newly spawned thread, so you wont execute the conditional break
(until the next time through the loop).

HTH, cheers (and have fun :)
Benjohn



benjohn

3/2/2006 7:23:00 AM

0

:( Sorry about the digest subject of that last post.


Mark Volkmann

3/2/2006 7:05:00 PM

0

On 3/2/06, Benjohn Barnes <benjohn@fysh.org> wrote:

> You should be able to begin as many concurrent telnet sessions to
> port 5000 as you wish, and anything typed on any will be pirated back
> at.

I think you meant to say "parroted back" instead of "pirated back",
although it's pretty funny since pirates are often assumed to own
parrots.

--
R. Mark Volkmann
Partner, Object Computing, Inc.


Lloyd Olson

7/15/2010 3:11:00 AM

0

Then you'll have to go over some basic checks. Power at the motor ? Power to
the small board nearby ? Power leaving the power driver board ? Try and
figure where you lose power. LTG :)

<dsaintos@hotmail.com> wrote in message
news:d9f942e4-e883-43a3-a3e3-64d9c8f7f906@r27g2000yqb.googlegroups.com...
>
I did go into test T19 and it is running and that is where I can make
the down switch open and close
and it registers on the display open and close and also says running.
No motor movement though.
I also checked the wire on the wire and reset connectors on the Motor
EMI PCB assembly.
All look good