[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Ruby threads and the system call

Vincent Fourmond

8/27/2006 8:17:00 AM


Hello !

I've recently had quite a fair bit of trouble with Ruby threads (on a
Linux box). I wrote three different programs (attached) that write
numbers from within threads:

* one with a standard puts
* one with a system "echo ..."
* one with a fork do system "echo ..." end

The first one behaves as expected (although the numbers are perfectly
ordered, which looks suspicious). In the second one, ruby never manages
to make a second system call in a thread (and finishes before the
subprograms are terminated). The third behaves a little better, but
crashes after, say, 3 to 4 system calls in a thread...

Is this true on other boxes ? Is it a flaw of my understanding of
threads, or a limitation inherent to the way threads are coded in Ruby ?
If that is so, it's really annoying - no way to delegate heavy tasks to
other well-written programs...

Thoughts ?

Vince
#!/usr/bin/ruby

10.times do |i|
Thread.start(i) do |i|
10.times do |j|
puts "#{i}.#{j}"
end
end
end

#!/usr/bin/ruby

10.times do |i|
Thread.start(i) do |i|
10.times do |j|
system "echo #{i}.#{j} "
end
end
end

#!/usr/bin/ruby

10.times do |i|
Thread.start(i) do |i|
10.times do |j|
fork do
system "echo #{i}.#{j} "
end
end
end
end

2 Answers

Paul Lutus

8/27/2006 11:34:00 AM

0

Vincent Fourmond wrote:

/ ...

> Thoughts ?

Try this code:

----------------------------------------

#!/usr/bin/ruby -w

system "rm temp.txt" if File.exists? "temp.txt"

10.times { |i|
x = Thread.new(i) {
10.times { |j|
fork {
system "echo #{i}, #{j} >> temp.txt"
}
Process::wait
}
}
x.join
}

system "wc -l temp.txt" # should print "100 temp.txt"

----------------------------------------

According to the documentation for "fork", "Process::wait" is needed to
avoid the creation of zombie processes. "x.join" assures that the log file
isn't written by multiple processes in a way that corrupts it.

If you want to test simultaneous independent threads, you could write to a
separate file per thread, then combine the files after all threads have
completed as an accuracy check. But I don't see this as anything but
multiple writes to a single file (or console output) that creates I/O
inconsistencies, in an otherwise consistent program.

> The third behaves a little better, but
> crashes after, say, 3 to 4 system calls in a thread...

As to "crash", what error messages did you see? How do you define "crash"?

This may be system-related. You might not have the resources required for
this program, if all threads and forks run at once. Just a guess.

--
Paul Lutus
http://www.ara...

Vincent Fourmond

8/27/2006 6:16:00 PM

0


Hello !

>
> 10.times { |i|
> x = Thread.new(i) {
> 10.times { |j|
> fork {
> system "echo #{i}, #{j} >> temp.txt"
> }
> Process::wait
> }
> }
> x.join

Great thanks, I had completely forgotten to call join for the
threads... By the way, the version with fork is around 4 times faster on
my box:

ruby test_threads_system.rb > /dev/null 0.04s user 0.10s system 21% cpu
0.639 total
ruby test_threads_system_fork.rb > /dev/null 0.00s user 0.04s system
25% cpu 0.171 total

Cheers and thanks !!

Vince