From: Chuck Remes Date: 2011-10-27T22:53:07+09:00 Subject: Re: Ruby and threading --Boundary_(ID_DSMxNr3J1iR0x7lvxAqKTQ) Content-type: text/plain; CHARSET=US-ASCII Content-transfer-encoding: 7BIT On Oct 26, 2011, at 10:40 PM, Josh Cheek wrote: > > As an aside, if I had a real need for parallelism, I'd probably select a > language better suited to it (e.g. Clojure). Maybe if the community offered > some good resources about how to safely develop parallel code I'd be more > comfortable using Ruby, but right now, I prefer the safety of the GIL. Please reread Tony Arcieri's response from October 19 where he shreds the idea that you can "prefer the safety of the GIL." There is *no* safety provided by the GIL. Let me reprint his code example again. Tony Arcieri wrote: > -- snip -- > require 'thread' > > numbers = [0] > threads = [] > #lock = Mutex.new > > 100.times do > threads << Thread.new do > size = nil > > begin > #lock.synchronize do > value = rand(101) > if value == numbers.last + 1 > sleep 0.01 > numbers << value > end > > size = numbers.size > #end > end while size < 100 > end > end > > threads.each(&:join) > p numbers > -- snip -- > > It's a bit contrived and goofy, but whatever. The output should look like > this: > > [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, > 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, > 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, > 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, > 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, > 97, 98, 99,100] > > However if you run the above code with the lock commented out, even on 1.9.2 > you'll get something like this instead: > > [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, > 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, > 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, > 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, > 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, > 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, > 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, > 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] > > Broken, thread-unsafe code is broken, thread-unsafe code. It doesn't matter > if it magically happens to work by accident in 1.9.2. It's still broken. It's. Still. Broken. The GIL provides a *false* sense of security. Don't rely on it. cr --Boundary_(ID_DSMxNr3J1iR0x7lvxAqKTQ)--