Hi all,

I learning ruby thread and faced to thread problem.

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

sum = 0

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

## puts sum

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

Please let me know what problem is.

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

sum = 0
mutex = Mutex.new

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

## puts sum

2010/11/17 Jaeyong L. [email protected]:

On 11/16/2010 11:50 PM, Jaeyong L. wrote:

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

Please let me know what problem is.

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

-Justin

On Wed, Nov 17, 2010 at 9:16 AM, Justin C. [email protected]
wrote:

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

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:

1.upto(1000) { |external|
sleep(rand(0.01))
local
}
}

sum = 0

puts sum

Kind regards

robert

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