From: Philip Scott Date: 2008-03-07T09:19:48+09:00 Subject: 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 :) 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.