Thread problem

Hi all,

I learning ruby thread and faced to thread problem.

Here's my test code that sum 1 to 1000.

···

--
threads = []

sum = 0

1.upto(1000) { |external|
  threads << Thread.new(external) { |local|
    sleep(rand(0.01))
    sum = sum + local
  }
}

threads.each() { |thread| thread.join() }

puts sum
--

I expected '500500' but output is smaller than. (ex: 499864)

Please let me know what problem is.

--
Posted via http://www.ruby-forum.com/.

I think that the reason of this problem is the simultaneous use of a
common resource. In your example, the common resource is the variable
*sum*. You need to use a Mutex object to avoid the simultaneous use of
that variable.
cf. Mutex class: http://ruby-doc.org/core/classes/Mutex.html

···

---
require 'thread'
threads =

sum = 0
mutex = Mutex.new

1.upto(1000) { |external|
   threads << Thread.new(external) { |local|
     sleep(rand(0.01))
     mutex.synchronize {
       sum = sum + local
     }
   }
}

threads.each() { |thread| thread.join() }

puts sum
---

2010/11/17 Jaeyong Lee <crizin@gmail.com>:

Hi all,

I learning ruby thread and faced to thread problem.
Here's my test code that sum 1 to 1000.

--
threads =

sum = 0

1.upto(1000) { |external|
threads << Thread.new(external) { |local|
sleep(rand(0.01))
sum = sum + local
}
}

threads.each() { |thread| thread.join() }

puts sum
--

I expected '500500' but output is smaller than. (ex: 499864)
Please let me know what problem is.

--
NOBUOKA Yuya

You are updating a shared variable "simultaneously" in separate threads, which is a very bad idea.

-Justin

···

On 11/16/2010 11:50 PM, Jaeyong Lee wrote:

Hi all,

I learning ruby thread and faced to thread problem.

Here's my test code that sum 1 to 1000.

--
threads =

sum = 0

1.upto(1000) { |external|
   threads<< Thread.new(external) { |local|
     sleep(rand(0.01))
     sum = sum + local
   }
}

threads.each() { |thread| thread.join() }

puts sum
--

I expected '500500' but output is smaller than. (ex: 499864)

Please let me know what problem is.

Absolutely correct. In this particular case using a shared resource
is not necessary since the state of that shared resource is only
accessed when all threads have terminated. One could do this as well:

threads =

1.upto(1000) { |external|
  threads << Thread.new(external) { |local|
   sleep(rand(0.01))
   local
}
}

sum = 0

threads.each() { |thread| sum += thread.value()}

puts sum

Kind regards

robert

···

On Wed, Nov 17, 2010 at 9:16 AM, Justin Collins <justincollins@ucla.edu> wrote:

On 11/16/2010 11:50 PM, Jaeyong Lee wrote:

Hi all,

I learning ruby thread and faced to thread problem.

Here's my test code that sum 1 to 1000.

--
threads =

sum = 0

1.upto(1000) { |external|
threads<< Thread.new(external) { |local|
sleep(rand(0.01))
sum = sum + local
}
}

threads.each() { |thread| thread.join() }

puts sum
--

I expected '500500' but output is smaller than. (ex: 499864)

Please let me know what problem is.

Race condition - Wikipedia

You are updating a shared variable "simultaneously" in separate threads,
which is a very bad idea.

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Y. NOBUOKA wrote in post #962070:

I think that the reason of this problem is the simultaneous use of a
common resource. In your example, the common resource is the variable
*sum*.

Or more explicitly: sum = sum + local is not an atomic operation.

Consider it as a sequence of steps:
1. retrieve value of 'sum'
2. retrieve value of 'local'
3. add them
4. store the result back in 'sum'

Now think what happens when two threads are doing this together. Let's
say the sum is currently 15, and the two threads want to add 6 and 7.

Thread A might get as far as completing steps 1-3, reading the value of
sum (15) and local (6) and computing the sum, then get switched out.

Thread B runs. It reads sum (15) and local (7), and computes the sum. It
stores 22 into 'sum'.

Thread A now resumes. It stores 21 into 'sum', overwriting the value
stored by Thread B.

Regards,

Brian.

···

--
Posted via http://www.ruby-forum.com/\.