Created
June 17, 2011 13:30
-
-
Save mikbe/1031419 to your computer and use it in GitHub Desktop.
Revisions
-
mikbe revised this gist
Jun 17, 2011 . 1 changed file with 16 additions and 8 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -33,30 +33,35 @@ def baz end f = Foo.new f2 = Foo.new lastBaz1 = -2 lastBaz2 = -2 baz1 = -1 baz2 = -1 count = 0 show_once = true while baz1 == baz2 last_one = "f.bar: #{f.bar}; baz1: #{baz1}; baz2: #{baz2}" f = Foo.new lastBaz1, lastBaz2 = baz1, baz2 t1 = Thread.new {sleep ((Time.now + 0.01 )- Time.now); baz1 = f.baz } t2 = Thread.new {sleep ((Time.now + 0.01) - Time.now); baz2 = f.baz } # make sure both threads are done time_out = 0 sleep 0.01 while (baz2 == lastBaz2 || baz1 == lastBaz1) && (time_out += 1) < 10 if time_out == 10 # Make sure it wasn't an error in the thread that caused the timeout t1.join t2.join puts "timeout reached" break end puts "#{f.threadsafe_mutex}: #{f.bar}" if (count+=1) % 100 == 0 GC.start if count % 100 == 0 # Verify instances are getting their own mutexes if show_once @@ -71,3 +76,6 @@ def baz puts "Thread collision: should never get here" puts "previous: #{last_one}" # <= Prove it's not remembering value from last iteration but is a real collision puts "current: f.bar: #{f.bar}; baz1: #{baz1}; baz2: #{baz2}" puts "Class mutex: #{f.class.threadsafe_class_mutex}" puts "instance mutex: #{f.threadsafe_mutex}" puts "instance mutex: #{f2.threadsafe_mutex}" -
mikbe revised this gist
Jun 17, 2011 . 1 changed file with 19 additions and 16 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,7 +4,7 @@ module ThreadSafe def self.included(base) base.extend(ThreadSafeClassMethods) base.threadsafe_class_mutex = Mutex.new end module ThreadSafeClassMethods @@ -33,38 +33,41 @@ def baz end f = nil f2 = Foo.new lastBaz1 = -2 lastBaz2 = -2 baz1 = -1 baz2 = -1 count = 0 last_one = "" show_once = true while baz1 == baz2 f = Foo.new lastBaz1, lastBaz2 = baz1, baz2 wait_til = Time.now + 0.01 Thread.new {sleep (wait_til - Time.now); baz1 = f.baz } Thread.new {sleep (wait_til - Time.now); baz2 = f.baz } # make sure both threads are done time_out = 0 sleep 0.01 while (baz2 == lastBaz2 || baz1 == lastBaz1) && (time_out += 1) < 100 puts "#{f.threadsafe_mutex}: #{f.bar}" if (count+=1) % 100 == 0 # Verify instances are getting their own mutexes if show_once show_once = false puts "Class mutex: #{f.class.threadsafe_class_mutex}" puts "instance mutex: #{f.threadsafe_mutex}" puts "instance mutex: #{f2.threadsafe_mutex}" end end puts puts "Thread collision: should never get here" puts "previous: #{last_one}" # <= Prove it's not remembering value from last iteration but is a real collision puts "current: f.bar: #{f.bar}; baz1: #{baz1}; baz2: #{baz2}" -
mikbe created this gist
Jun 17, 2011 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,70 @@ require 'thread' module ThreadSafe def self.included(base) base.extend(ThreadSafeClassMethods) base.threadsafe_class_mutex = Mutex.new # <= This should be threadsafe by its very nature end module ThreadSafeClassMethods attr_accessor :threadsafe_class_mutex end def threadsafe_mutex self.class.threadsafe_class_mutex.synchronize { @mutex ||= Mutex.new } end end class Foo include ThreadSafe attr_accessor :bar def baz threadsafe_mutex.synchronize { @bar ||= rand(10000000000) } end end f = Foo.new f2 = Foo.new baz1 = -1 baz2 = -1 count = 0 last_one = "" show_once = true while baz1 == baz2 last_one = "f.bar: #{f.bar}; baz1: #{baz1}; baz2: #{baz2}" f.bar = nil wait_til = Time.now + 0.01 Thread.new {sleep (wait_til - Time.now); baz1 = f.baz } Thread.new {sleep (wait_til - Time.now); baz2 = f.baz } sleep 0.02 count += 1 if count == 100 puts "working: #{last_one}" count = 0 end if show_once show_once = false # only want to run these after the classes have had a chance to instnatiate the mutexes, # not force them to be instantiated (thus negating the reason for the test) puts "Class mutex: #{f.class.threadsafe_class_mutex}" puts "instance mutex: #{f.threadsafe_mutex}" puts "instance mutex: #{f2.threadsafe_mutex}" # Just to verify instances are getting their own mutexes end end puts puts "Thread collision" puts "previous: #{last_one}" # Just to prove it's not remembering value from last iteration but is a real collision puts "current: f.bar: #{f.bar}; baz1: #{baz1}; baz2: #{baz2}"