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

Philip Scott wrote:

Fill two identical arrays full of 10 random strings

for x in (0…100)
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 C. [email protected]:

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