# Two Ruby threading questions

**URL:** <https://www.ruby-forum.com/t/two-ruby-threading-questions/72457>\
**Category:** Ruby\
**Created:** [February 23, 2006, 6:40pm UTC](https://www.ruby-forum.com/t/two-ruby-threading-questions/72457 "2006-02-23T18:40:16Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![codeslinger](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/e9a140/32.png) [@codeslinger](https://www.ruby-forum.com/u/codeslinger)\
**Post date:** [February 23, 2006, 6:40pm UTC](https://www.ruby-forum.com/t/two-ruby-threading-questions/72457/1 "2006-02-23T18:40:16Z")

</div>

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.

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  
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?

Thanks in advance for any help you can provide.

---

<div class="post-metadata">

**Author:** ![codeslinger](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/e9a140/32.png) [@codeslinger](https://www.ruby-forum.com/u/codeslinger)\
**Post date:** [February 23, 2006, 7:16pm UTC](https://www.ruby-forum.com/t/two-ruby-threading-questions/72457/2 "2006-02-23T19:16:32Z")

</div>

Nevermind about question 2 above. I figured it out. Defining the  
lambdas in the previous manner put them in the class scope, not object  
instance scope. Here’s how to make that work:

puma:~\> cat a.rb  
require ‘socket’

class X  
def thread\_init  
@connection\_main = 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  
@server\_main = lambda do |srv|  
begin  
while true  
s = srv.accept  
Thread.start s, &@connection\_main  
end  
rescue =\> e  
puts “#{e.message}:\n\t#{e.backtrace.join(”\n\t")}"  
ensure  
srv.close  
end  
end  
end

def initialize  
srv = TCPServer.new nil, 8008  
Thread.abort\_on\_exception = true  
thread\_init  
Thread.start srv, &@server\_main  
while true  
# doing main thread stuff in here  
sleep 5  
puts Thread.list.join(’,’)  
end  
end

def handle\_sock\_data data  
# do something with data here  
puts “called handle\_sock\_data: ‘#{data.strip}’”  
end

end # class X

x = X.new  
puma:~\>

This outputs:

puma:~\> ruby a.rb  
called handle\_sock\_data: ‘hello’  
#Thread:0xb7d0fe3c,#Thread:0xb7d0fd10,#Thread:0xb7d1e748  
called handle\_sock\_data: ‘goodbye’  
#Thread:0xb7d0fe3c,#Thread:0xb7d1e748  
#Thread:0xb7d0fe3c,#Thread:0xb7d1e748  
#Thread:0xb7d0fe3c,#Thread:0xb7d1e748  
a.rb:37:in `sleep': Interrupt from a.rb:37:in`initialize’  
from a.rb:49  
puma:~\>

I Ctrl-C’d it there at the end.

It would seem that I don’t need to worry about the Thread  
detached/setDaemon functionality, either, since the client  
@connection\_main threads seem to get cleaned up without having to  
explicitly join them. Arigatou gozaimasu, Matsumoto-san 🙂

---

<div class="post-metadata">

**Author:** ![codeslinger](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/e9a140/32.png) [@codeslinger](https://www.ruby-forum.com/u/codeslinger)\
**Post date:** [February 23, 2006, 7:16pm UTC](https://www.ruby-forum.com/t/two-ruby-threading-questions/72457/3 "2006-02-23T19:16:33Z")

</div>

codeslinger wrote:

> “detached” state in pthread lingo.  
> No. You will have to terminate them manually on exit.

> ```
> 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.

> ```
> while true
> 
> ```
> 
> ConnectionMain = lambda do |sock|
> 
> ```
> a.rb:22
> 
> ```
> 
> 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](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

```

---

<div class="post-metadata">

**Author:** ![codeslinger](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/e9a140/32.png) [@codeslinger](https://www.ruby-forum.com/u/codeslinger)\
**Post date:** [February 23, 2006, 8:14pm UTC](https://www.ruby-forum.com/t/two-ruby-threading-questions/72457/4 "2006-02-23T20:14:14Z")

</div>

Robert K. wrote:

> codeslinger wrote:
> 
> > 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.

If this is true (see my last post), then this is a design flaw in  
Ruby’s threading library. This particular application will be  
long-running and cannot afford to have dead threads laying around  
waiting for exit (which hopefully will never come). I understand that I  
can join the threads in the main loop periodically to avoid this fate,  
but that is still hackish. Perhaps a Thread#join\_on\_exit= or  
Thread#autojoin= or Thread#detach= method would fit the bill for this?

> the processing.  
> The above code was just an example. That’s not what the real code does  
> (its a port of some Java code), but since it is overwhelmingly large, I  
> wanted to show just the crux of the problem without all the other code  
> clouding the issue. My example wasn’t the best Ruby, as you’ve pointed  
> out 😉

> ```
> end
> end
> end
> 
> ```
> 
> end

Yeah, I am doing something similar in the real code (see below), but I  
have to hunt around for a port to listen on, so the exact code above  
wouldn’t work for me. Plus, as I’ve said, the code inside the lambdas  
is kind of large, and would cloud readability if I put it in the middle  
of the initialize function. The real code reads:

 def initialize datadir, namenodeaddr [...] thread\_main\_init ss = nil tmpport = 50010 machinename = DataNode.get\_local\_ip namenodeaddr[0] until ss begin ss = TCPServer.new machinename, tmpport LOG.info "Opened server at #{tmpport}" rescue IOError =\> e LOG.info "Could not open server at #{tmpport}, trying new port" tmpport += 1 end end @localname = "#{machinename}:#{tmpport}" @dataxceive\_srv = Thread.start ss, &@data\_xceive\_server [...] end

The @data\_xceive\_server is one of the lambda’s that I am creating in  
the thread\_main\_init() method (the others are for client connection  
handling).

> Take care to synchronize access to shared resources in connection  
> handling.

I got that. Thanks for all the help, Robert.

---

<div class="post-metadata">

**Author:** ![codeslinger](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/e9a140/32.png) [@codeslinger](https://www.ruby-forum.com/u/codeslinger)\
**Post date:** [February 23, 2006, 10:58pm UTC](https://www.ruby-forum.com/t/two-ruby-threading-questions/72457/5 "2006-02-23T22:58:50Z")

</div>

removed\_email\_address@domain.invalid wrote:

> On the other hand, threads are not blithely terminated when some  
> “master” thread exits. To complete your program, you would want to  
> signal each thread in an appropriate fashion so that it can finish  
> up what it’s doing and exit cleanly.

Aren’t other threads terminated?

$ ruby -e ‘Thread.new {sleep}; puts “done!”’  
done!

But, as you say, cleanly stopping threads (perhaps using ensure blocks)  
is a good idea:

$ ruby -e ‘Thread.new {begin; sleep; ensure puts “thread done”; end};  
puts “done!”’  
done!  
thread done

---

<div class="post-metadata">

**Author:** ![codeslinger](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/e9a140/32.png) [@codeslinger](https://www.ruby-forum.com/u/codeslinger)\
**Post date:** [February 23, 2006, 10:37pm UTC](https://www.ruby-forum.com/t/two-ruby-threading-questions/72457/6 "2006-02-23T22:37:30Z")

</div>

Quoting codeslinger [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> If this is true (see my last post), then this is a design flaw in  
> Ruby’s threading library. This particular application will be  
> long-running and cannot afford to have dead threads laying around  
> waiting for exit (which hopefully will never come).

If the dead threads aren’t referenced anywhere, the garbage  
collector should clean them up. Completed threads don’t need to be  
joined before destruction.

On the other hand, threads are not blithely terminated when some  
“master” thread exits. To complete your program, you would want to  
signal each thread in an appropriate fashion so that it can finish  
up what it’s doing and exit cleanly.

-mental

---

<div class="post-metadata">

**Author:** ![codeslinger](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/e9a140/32.png) [@codeslinger](https://www.ruby-forum.com/u/codeslinger)\
**Post date:** [February 24, 2006, 10:35am UTC](https://www.ruby-forum.com/t/two-ruby-threading-questions/72457/7 "2006-02-24T10:35:20Z")

</div>

codeslinger wrote:

> If this is true (see my last post), then this is a design flaw in  
> Ruby’s threading library. This particular application will be  
> long-running and cannot afford to have dead threads laying around  
> waiting for exit (which hopefully will never come). I understand that  
> I can join the threads in the main loop periodically to avoid this  
> fate, but that is still hackish. Perhaps a Thread#join\_on\_exit= or  
> Thread#autojoin= or Thread#detach= method would fit the bill for this?

Joining won’t help because essentially this prevents the process from  
terminating. I was wrong though (see Joel’s posting). Pickaxe II  
states  
in chapter 11 (page 137) that all threads are killed when the main  
thread  
exits. That’s why threaded programs usually end with a loop that joins  
over all threads. Somehow this joining became second nature that I  
completely overlooked that here. So to put things straight, in Java  
lingo  
all Ruby threads but the main thread are daemon threads.

> I got that. Thanks for all the help, Robert.

You’re welcome - although I mislead you on the nature of threads. I’m  
sorry for that.

The usual idiom I follow is to create all threads that must do their  
work,  
signal them for termination depending on the nature of the processing  
done  
(e.g. send a terminator message through a queue for a producer consumer  
scenario) and have main thread join all threads before exiting.

What kind of application are you building?

Kind regards

```
robert
```
