Threading weirdness

Hi guys,

I'd be grateful if someone could take a look at the following two test cases I made after noticing some strange behavior with ruby threads. I think the
code speaks clearer than I could, but in essence if you create a lot of threads from the same block all reading from a single array, things go wierd. It is almost as if variables get mixed up between the threads. I am fairly sure this is not expected behavior.. If I make the threads as part of a class, this doesn't seem to happen.

The first does as you'd expect and never terminates. The second invariably stops after a few thousand iterations when my exception gets raised.

I hope I am not wasting your time and have overlooked some glaringly obvious details about threads, but I am banging my head on the wall here :slight_smile:

Cheers,

Philip

################################ PROGRAM 1: WORKS, NEVER TERMINATES
require 'thread'
require 'digest/md5'

# A little class that takes references to two arrays in its constructor
# then starts a thread which compares random elements from the two and
# throws an exception if they are ever different.
class Tester
   def initialize (arrayA, arrayB)
     @arrayA = arrayA
     @arrayB = arrayB
     Thread.start {mainloop}
   end

   def mainloop
     testThread = Thread.new do
       while true
         i = rand(9)
         if (@arrayA[i] != @arrayB[i])
           raise Exception.new("Threading Fuckup")
         end
       end
     end
   end
end

a = []
b = []

# Fill an array with 10 random strings, and mirror this
# in another identical array.
for i in (0..9)
    a[i] = Digest::MD5.hexdigest(rand(1000).to_s).to_s
    b[i] = a[i]
end

print "Starting threads...\n"
Thread.abort_on_exception = true

# Start 100 threads comparing the elements in the array
for x in (0..100)
   Tester.new(a,b)
end

print "And we're off"

# And spin forever
while true do
end

######################################## PROGRAM 2: DOESNT WORK, TERMINATES
require 'thread'
require 'digest/md5'

a = []
b = []

# Fill two identical arrays full of 10 random strings
for i in (0..9)
    a[i] = Digest::MD5.hexdigest(rand(1000).to_s).to_s
    b[i] = a[i]
end

print "Starting threads\n"
Thread.abort_on_exception = true

# Start a hundred threads reading items from the two arrays and comparing them
for x in (0..100)
     testThread = Thread.new do
         while true
             i = rand(9)
             if (a[i] != b[i])
                 raise Exception.new("Threading Broke")
             end
         end
     end
end

print "And we're off"

# Spin forever (or at least until an Exception gets thrown)
while true do
end

···

----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.

Philip Scott wrote:

Hi guys,

######################################## PROGRAM 2: DOESNT WORK, TERMINATES
require 'thread'
require 'digest/md5'

a =
b =

# Fill two identical arrays full of 10 random strings
for i in (0..9)
   a[i] = Digest::MD5.hexdigest(rand(1000).to_s).to_s
   b[i] = a[i]
end

print "Starting threads\n"
Thread.abort_on_exception = true

# Start a hundred threads reading items from the two arrays and comparing them
for x in (0..100)
    testThread = Thread.new do
        while true
            i = rand(9)
            if (a[i] != b[i])
                raise Exception.new("Threading Broke")
            end
        end
    end
end

print "And we're off"

# Spin forever (or at least until an Exception gets thrown)
while true do
end

The variable 'i' is shared across all threads because it was created when you initialized the arrays and is still in scope when you create the threads.

-Justin

Quoting Justin Collins <justincollins@ucla.edu>:

The variable 'i' is shared across all threads because it was created
when you initialized the arrays and is still in scope when you create
the threads.

Well don't I feel like a dolt :slight_smile:

Thank you ever so much, you have restored my faith in Ruby :slight_smile:

Cheers,

Philip

···

----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.