Re: Threading in new C++ standard
On May 2, 2:35 am, "Boehm, Hans" <hans.bo...@hp.com> wrote:
On May 1, 2:26 pm, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
wrote:> On Apr 28, 8:42 pm, "Boehm, Hans" <hans.bo...@hp.com> wrote:
On Apr 21, 10:07 am, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
wrote:
[...]
In
particular, it I write the equivalent of
Thread 1:
x = 42;
x_init = true;
Thread 2:
while (!x_init);
assert(x == 42);
this can fail (and in fact is incorrect) even if x_init is atomic.
Of course it is incorrect. Here both `x' and `x_init' are shared
variables but you miss to declare them as such. Furthermore, you are
trying to access them `in sequential manner' i.e. as if they were
variables in a sequential program. However, then, why are you
wondering that an incorrect concurrent program can fail?
This is correct in Java and the C++0x working paper if x_init is
volatile(Java)/atomic(C++). The variable x cannot be simultaneously
accessed, hence there is no data race on x. And x_init is effectively
declared shared.
First of all, can you please decide which statement of yours is what
you really hold:
1) `this can fail (and in fact is incorrect) even if x_init is
atomic.'
2) `This is correct in Java and the C++0x working paper if x_init is
volatile(Java)/atomic(C++).'
Both statements are made by you and both refer to the same code
fragment. The only difference is that the first statement is made by
you for your original code fragment and the second one is made in
response to my comments.
What do you really think about it? Is it correct or incorrect?
Besides, I can admit that if you declare `x_init' volatile(Java)/
atomic(C++), the access to `x_init' will be exclusive (as if there
would be a tiny Critical Region defined).
On the other hand, it is a typical concurrent bug to think that if
`x_init' is volatile(Java)/atomic(C++), that has any effect on
accessing another variable `x' subsequent to inspecting atomically the
volatile(Java)/atomic(C++) one. The atomicity is valid for one and
only one operation individually. Two atomic operations in a sequence
cannot be build on the result of each other. You need a Critical
Region for that.
In fact in concurrent programming you can assume any long delay
between two subsequent operations and if those two operations together
is not declared to be an atomic one (see Critical Region) anything may
happen in between.
Thread 2:
while (!x_init);
// <--- x_init may become false right here
// delay(1 day); <--- e.g. x=33
assert(x == 42);
In this case anything may happen with `x' during the delay because
`while (!x_init);' and `assert(x == 42);' are not inside the same
Critical Region. Thus, you cannot be sure about the assert.
On the other hand, let us consider
Thread 2:
with (x) when (x == 42) {
// delay(1 day); <--- x cannot be accessed
// do whatever you want to do when x==42
}
In this case anything may happen during the delay _except_ with `x'
since we expressed our intention that we want to do something with it
when the condition holds (see the Conditional Critical Region).
Best Regards,
Szabolcs