Newby question: Is += atomic for integers?

R

rj-cole

Hi,

Can the following program produce counts that are wrong?

class Test
attr_accessor :count
def initialize
@count = 0
end
end

$test = Test.new

def my_function_called_by_many_threads
...
$test.count += 1
...
end

Any why is the following a syntax error?

class Test
def +=(value)
end
end

i.e why can't I define the += operator?

regards,

Richard.
 
E

Eric Hodel

Hi,

Can the following program produce counts that are wrong?

class Test
attr_accessor :count
def initialize
@count = 0
end
end

$test = Test.new

def my_function_called_by_many_threads
...
$test.count += 1
...
end

Yes. += is just syntax sugar. It gets expanded:

$ parse_tree_show -f
a += 1
[[:class,
:Example,
:Object,
[:defn,
:example,
[:scope,
[:block,
[:args],
[:lasgn, :a, [:call, [:lvar, :a], :+, [:array, [:lit, 1]]]]]]]]]
Any why is the following a syntax error?

class Test
def +=(value)
end
end

i.e why can't I define the += operator?

+= is not an operator, it is syntax sugar.
 
M

Minkoo Seo

rj-cole said:
Can the following program produce counts that are wrong?

class Test
attr_accessor :count
def initialize
@count = 0
end
end

$test = Test.new

def my_function_called_by_many_threads
...
$test.count += 1
...
end

Yes.

There's two problem.

(1) Even though an operation seems to be atomic, say, "a+1", it might
not be atomic in the machine level. Such an example is operations on
double, and class references. In some cases, assignment of double
variable might be done two steps.

(2) Especially if $test were shared by multiple threads which runs on
SMP, though current version of ruby core does not support it - I hope
it will - , you have to use mutex(synchronize). Otherwise, different
threads may see different values because each processor uses own cache.
This rule even applies to Java, C++, etc.

Simple and best solution to these problems is to use synchronization
whenever needed.

Minkoo Seo
 
R

Robert Klemme

Minkoo said:
Yes.

There's two problem.

(1) Even though an operation seems to be atomic, say, "a+1", it might
not be atomic in the machine level. Such an example is operations on
double, and class references. In some cases, assignment of double
variable might be done two steps.

(2) Especially if $test were shared by multiple threads which runs on
SMP, though current version of ruby core does not support it - I hope
it will - , you have to use mutex(synchronize). Otherwise, different
threads may see different values because each processor uses own
cache. This rule even applies to Java, C++, etc.

Simple and best solution to these problems is to use synchronization
whenever needed.

I strongly support that! Always do proper synchronization even if a non
synchronized version seems to work. It's likely to break as soon as the
code runs on another platform (e.g. Java VM). These bugs are hard to find
and also there is a documentation advantage that comes with proper MT
design.

Kind regards

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,293
Messages
2,571,500
Members
48,187
Latest member
ashish_758

Latest Threads

Top