From: Robert Klemme Date: 2006-02-24T03:13:33+09:00 Subject: Re: Two Ruby threading questions codeslinger wrote: > Hi all, > > I have a number of issues that I'm dealing with regarding Ruby threads > and I was wondering if someone might point me in the right direction > with some or all of them: > > 1. Is there a commensurate to Java's setDaemon() functionality for > Ruby? I've looked around on the Web, but I can't find reference to > anything and there's nothing in the docs about it. For those not > familiar with Java, setDaemon() is equivalent to setting a thread to a > "detached" state in pthread lingo. No. You will have to terminate them manually on exit. > 2. Here's some demonstration code that will help understand this next > issue: > > puma:~> cat a.rb > require 'socket' > > class X > def initialize > srv = TCPServer.new nil, 8008 > Thread.abort_on_exception = true > Thread.start srv, &ServerMain > while true > # doing main thread stuff in here Don't do that. Simply fork off a thread that does the connection handling and return. Initializers are for initialization but should not contain the processing. > sleep 10 > end > end > > def handle_sock_data data > # do something with data here > end > > ServerMain = lambda do |srv| > begin > while true > s = srv.accept > Thread.start s, &ConnectionMain > end > rescue => e > puts "#{e.message}:\n\t#{e.backtrace.join("\n\t")}" > ensure > srv.close > end > end > > ConnectionMain = lambda do |sock| > begin > data = sock.gets > handle_sock_data data > rescue => e > puts "#{e.message}:\n\t#{e.backtrace.join("\n\t")}" > raise e > ensure > sock.close rescue nil > end > end > > end # class X > > x = X.new > puma:~> > > Here's what I get when I run this, connect to it and send it a string: > > puma:~> ruby a.rb > undefined method `handle_sock_data' for X:Class: > a.rb:34 > a.rb:22 > a.rb:7:in `initialize' > a.rb:45 > a.rb:34: undefined method `handle_sock_data' for X:Class > (NoMethodError) > from a.rb:22 > from a.rb:7:in `initialize' > from a.rb:45 > puma:~> > > Since ServerMain and ConnectionMain are lambdas, I would have expected > them to be able to locate the handle_sock_data() method. Why can't > they, and is there some way for me to get them to be able to see said > method? Your lambdas are class level constants but the method is an instance method. You rather want one lambda instance per onstance of X. But blocks will do the job as well. Did you check the example for TCPServer? It's below this: http://www.ruby-doc.org/docs/ProgrammingRuby/html/lib_network.html#SOCKSSocket.close require 'socket' class X attr_reader :thread def initialize @thread = Thread.new( TCPServer.new( nil, 8008 ) ) do |server| while ( sess = server.accept ) Thread.new(sess) do |session| handle_data sess.gets end end end end def handle(data) ... end end x=X.new # do other stuff puts "server started" # wait for termination x.thread.join Take care to synchronize access to shared resources in connection handling. Kind regards robert