# Newbie question regarding threads and system commands

**URL:** <https://www.ruby-forum.com/t/newbie-question-regarding-threads-and-system-commands/77188>\
**Category:** Ruby\
**Created:** [November 25, 2006, 12:01am UTC](https://www.ruby-forum.com/t/newbie-question-regarding-threads-and-system-commands/77188 "2006-11-25T00:01:35Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![jasonmorrison](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/47e85d/32.png) [@jasonmorrison](https://www.ruby-forum.com/u/jasonmorrison)\
**Post date:** [November 25, 2006, 12:01am UTC](https://www.ruby-forum.com/t/newbie-question-regarding-threads-and-system-commands/77188/1 "2006-11-25T00:01:35Z")

</div>

Sorry if I’m bothering you all again… This is my first program that  
runs  
a) threads and b) `system commands`, so I apologize for being a newbie.  
What  
I’m trying to do is ping multiple parts of a site to help an tech  
support  
guy (me) in figuring out where a point of failure is at a remote  
location.  
The reason I’m using threads: I want it to be faster than me typing  
across  
multiple cmd windows. The problem: it’s taking 15+ seconds when it  
works.  
I’ve been tinkering now with it for a few days, and I either get the  
program  
to end in 1 second (killing the child threads before they are done) or I  
get  
the 15 second problem. I’m just not real sure where to put the  
Thread.jointo make this run smoothly - nor am I sure that  
thread.join is the solution.

Joel VanderWerf suggested mapping stuff, but I’m not doing this by IP  
address (his solution the other day involved ping 192.168.1.#{i}) and I  
couldn’t quite figure out how to modify his code to fit mine.

code (with some stuff obfuscated)

def pingsite(site, type)  
result = `ping -n 4 #{site}-#{type}-1`.chomp  
return result  
end  
puts “What site?”  
sitelocation = gets.chomp  
t0 = Time.now  
data = “”  
sitetype=[“something”, “somethingelse”, “again”, “more”, “otherstuff”]  
sitetype.each do |type|  
type=Thread.new do  
puts pingsite(sitelocation, type)  
end  
type.join  
end  
#sitetype.join  
t1 = Time.now  
puts “Finished in #{t1 - t0} seconds”

Output:  
Finished in 14.711 seconds

with sitetype.join uncommented and type.join commented, I get this:  
What site?  
0110  
Finished in 1.051 seconds

Can someone explain to me what I’m doing wrong?

---

<div class="post-metadata">

**Author:** ![jasonmorrison](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/47e85d/32.png) [@jasonmorrison](https://www.ruby-forum.com/u/jasonmorrison)\
**Post date:** [November 25, 2006, 6:42am UTC](https://www.ruby-forum.com/t/newbie-question-regarding-threads-and-system-commands/77188/2 "2006-11-25T06:42:42Z")

</div>

This is one possible solution, which seems to work fine (it takes 3.14  
seconds on my system to ping 3 web sites). Bottom line: you need to keep  
a list of the threads and join all of them in the calling code. Hope  
this helps. I recommend that you get a copy of the “Pickaxe” book  
(Programming Ruby: The Pragmatic Programmers Guide, 2nd edition) , which  
has a very good section on threading and lots of examples. In the  
meantime, you can read this from the first edition:

## [http://www.rubycentral.com/book/tut\_threads.html](http://www.rubycentral.com/book/tut_threads.html)

require ‘thread’

class SystemExecutor

# Returns array [[cmd, response], [cmd, response], …]

def SystemExecutor.run(system\_cmd\_list)  
thread\_list = []  
system\_response\_list = []  
srl\_mutex = Mutex.new

```
system_cmd_list.each do |cmd|
  thread_list << Thread.new do
    begin
      response = %x{ #{cmd} }
      srl_mutex.synchronize do
        system_response_list << [cmd, response]
      end
    rescue Exception => exc
      srl_mutex.synchronize do
        system_response_list << [cmd, exc]
      end
    end
  end
end

thread_list.each { |thr| thr.join }
system_response_list

```

end  
end

puts “Starting ping”  
start\_time = Time.now  
resp = SystemExecutor.run([‘ping [www.ruby-forum.org](http://www.ruby-forum.org)’, ‘ping  
[www.sourceforge.net](http://www.sourceforge.net)’, ‘ping [www.google.com](http://www.google.com)’])  
elapsed\_time = Time.now - start\_time

resp.each do |cmd, resp|  
puts “Command: #{cmd}”, ‘-’ \* 20  
puts “Response:\n”, ‘-’ \* 20, “#{resp}”  
end

puts “Elapsed time: #{elapsed\_time} seconds.”

---

<div class="post-metadata">

**Author:** ![jasonmorrison](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/47e85d/32.png) [@jasonmorrison](https://www.ruby-forum.com/u/jasonmorrison)\
**Post date:** [November 25, 2006, 2:13pm UTC](https://www.ruby-forum.com/t/newbie-question-regarding-threads-and-system-commands/77188/3 "2006-11-25T14:13:03Z")

</div>

Maybe there’s something wrong with my system here at work then…  
because  
this took 11.something seconds to run on my machine. I’ll test again  
from  
home (both xp pro systems)

---

<div class="post-metadata">

**Author:** ![jasonmorrison](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/47e85d/32.png) [@jasonmorrison](https://www.ruby-forum.com/u/jasonmorrison)\
**Post date:** [November 25, 2006, 4:01pm UTC](https://www.ruby-forum.com/t/newbie-question-regarding-threads-and-system-commands/77188/4 "2006-11-25T16:01:12Z")

</div>

As it turns out, your program runs fine (\<4 seconds) if I change the  
ping  
destinations to something on the internal network. Looks like a router  
is  
misconfigured somewhere. Thanks!
