# Multiple threads on single port

**URL:** <https://www.ruby-forum.com/t/multiple-threads-on-single-port/62617>\
**Category:** Ruby\
**Created:** [June 6, 2006, 4:54pm UTC](https://www.ruby-forum.com/t/multiple-threads-on-single-port/62617 "2006-06-06T16:54:52Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![stuartbrand](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/5f9b8f/32.png) [@stuartbrand](https://www.ruby-forum.com/u/stuartbrand)\
**Post date:** [June 6, 2006, 4:54pm UTC](https://www.ruby-forum.com/t/multiple-threads-on-single-port/62617/1 "2006-06-06T16:54:52Z")

</div>

Hi all

Can I use Ruby threads to have more then 1 server process running on the  
same port

something like

require ‘socket’  
port = (ARGV[0] || 80).to\_i  
server = TCPServer.new(‘localhost’, port)  
threads = []

10.times do |i|  
threads[i] = Thread.new {  
while (session = server.accept)  
puts “Request: #{session.gets}”  
session.print “HTTP/1.1 200/OK\r\nContent-type: text/html\r\n\r\n”  
session.print “

# #{Time.now}
\r\n”  
session.close  
end  
}  
end

Would this produce 10 processes that could take independent connection?

---

<div class="post-metadata">

**Author:** ![stuartbrand](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/5f9b8f/32.png) [@stuartbrand](https://www.ruby-forum.com/u/stuartbrand)\
**Post date:** [June 6, 2006, 6:03pm UTC](https://www.ruby-forum.com/t/multiple-threads-on-single-port/62617/2 "2006-06-06T18:03:58Z")

</div>

Stuart B. wrote:

> Hi all
> 
> Can I use Ruby threads to have more then 1 server process running on the  
> same port
> 
> something like

[… example elided …]

Not quite. I believe you can only have one thread listening to a port  
at a given time. The idiom generally is to accept the connection in one  
thread, and then pass the accepted connection to a different thread for  
processing. So one thread handles accepting and multiple threads manage  
the processing.

– Jim W.

---

<div class="post-metadata">

**Author:** ![stuartbrand](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/5f9b8f/32.png) [@stuartbrand](https://www.ruby-forum.com/u/stuartbrand)\
**Post date:** [June 6, 2006, 6:37pm UTC](https://www.ruby-forum.com/t/multiple-threads-on-single-port/62617/3 "2006-06-06T18:37:55Z")

</div>

On 6/6/06, Stuart B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> threads = []  
> }  
> end
> 
> Would this produce 10 processes that could take independent connection?

This will probably create multiple threads that accept connections. I  
only did  
while(session = server.accept)  
Thread.new{…}  
end  
and it was in C. But you should be aware of the fact that depending on  
the request processing you do in your thread you may not get any  
thread switch until the request is handled. But at least print should  
probably trigger the ruby thread scheduler.

HTH

Michal

---

<div class="post-metadata">

**Author:** ![stuartbrand](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/5f9b8f/32.png) [@stuartbrand](https://www.ruby-forum.com/u/stuartbrand)\
**Post date:** [June 6, 2006, 6:50pm UTC](https://www.ruby-forum.com/t/multiple-threads-on-single-port/62617/4 "2006-06-06T18:50:36Z")

</div>

It works, but not terribly well. Whenever you call TCPServer#accept in a  
program with more than one thread, the acceptor socket goes on a wait  
queue  
inside Ruby until it’s readable- it doesn’t cross into the kernel. But I  
tried your program and stress-tested it with ten threads, and  
performance  
was abysmal. So I’d guess there’s some interaction with Ruby’s thread  
scheduler that isn’t quite normal. I’m not sure what you’re trying to do  
but  
you might be better off calling accept in one thread and passing the  
accepted sockets to a thread pool, or using nonblocking IO. Another  
standard  
alternative is to fork a process after accepting each socket- this is a  
perfectly good solution if your performance needs are low.

---

<div class="post-metadata">

**Author:** ![stuartbrand](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/5f9b8f/32.png) [@stuartbrand](https://www.ruby-forum.com/u/stuartbrand)\
**Post date:** [June 6, 2006, 6:47pm UTC](https://www.ruby-forum.com/t/multiple-threads-on-single-port/62617/5 "2006-06-06T18:47:25Z")

</div>

On Tuesday 06 June 2006 8:55 am, Stuart B. wrote:

> session.print “HTTP/1.1 200/OK\r\nContent-type: text/html\r\n\r\n”  
> session.print “
> 
> # #{Time.now}
> \r\n”  
> session.close  
> end  
> }  
> end

Don’t do this.

Just have a thread of execution that is in a while loop doing the  
accepts on  
the socket, and have it spawn threads to handle the connections.

def handle\_connection(session)  
puts “Request: #{session.gets}”  
session.print “HTTP/1.1 200/OK\r\nContent-type: text/html\r\n\r\n”  
session.print “

# #{Time.now}
\r\n”  
session.close  
end

while (session = server.accept)  
Thread.new {handle\_connection(session)}  
end

Kirk H.

---

<div class="post-metadata">

**Author:** ![stuartbrand](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/5f9b8f/32.png) [@stuartbrand](https://www.ruby-forum.com/u/stuartbrand)\
**Post date:** [June 6, 2006, 8:53pm UTC](https://www.ruby-forum.com/t/multiple-threads-on-single-port/62617/6 "2006-06-06T20:53:12Z")

</div>

Ok, the final code for this example I have done is

require ‘socket’  
port = (ARGV[0] || 123).to\_i  
server = TCPServer.new(‘localhost’, port)  
threads = []

10.times do |i|  
threads[i] = Thread.new {  
while (session = server.accept)  
puts “Request: #{session.gets}”  
session.print “HTTP/1.1 200/OK\r\nContent-type:  
text/html\r\n\r\n”  
session.print  
“

# #{Time.now}
\r\n”  
session.close  
end  
}  
end

threads.each { |t| t.join}

However, the only stress I can do is the ab apache test, this shows the  
same 1, 10 or 100 threads, how do I do a proper stress test??

Many thanks

Stuart
