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
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.