Re: Threads: incompatibilities between C and C++?
On 2012-05-23 08:25:27 +0000, Rani Sharoni said:
On May 22, 9:53 pm, Volker Lukas <vlu...@gmx.de> wrote:
Rani Sharoni wrote:
[...]> 30.3.1.2/5 might add a bit more to my confusion:
"Synchronization: The completion of the invocation of the
constructor synchronizes with the beginning of the invocation of
the copy of f."
I'm not sure about the meaning of this paragraph and why it's
actually required.
I think according to section 1.10 in the standard it means that the
new thread of execution can assume that the std::thread object is
fully constructed
I guess you are right though the "with the beginning of the
invocation" text is a bit confusing compared with traditional
threading for which threads can be created in a suspended state
(i.e. there is a separation between the thread object creation and
the invocation so no such synchronization specification is
required).
The specification of the semantics of multi-threading in C++ is based
entirely on the memory model (1.10). The memory model, in turn,
defines the visibility of data modifications in terms of library
function calls that make visiblity guarantees. For example,
int i = 0;
std::atomic_int ai = 0;
// thread 1:
i = 3;
ai.store(4);
// thread 2:
while (ai.load() != 4)
; /* busy wait */
assert(i == 3);
The store to ai in thread 1 guarantees sequential consistency, as does
the load from ai in thread 2. That, in turn, requires that the value
stored into i in thread 1 (which precedes the store to ai) must be
visible in thread 2, if thread 2 has seen the value stored in ai by
thread 1 (that's the point of the while loop).
In memory-model terms, the return from the call to store() in thread 1
*synchronizes with* the call to load() in thread 2.
That's the fundamental vocabulary here. The description of the
relation between the thread constructor and the thread function uses
the same vocabulary: the return from the constructor synchronizes with
the start of the thread function. That is, this has to work:
int i = 0;
void f() {
assert(i == 3);
}
int main() {
i = 3;
std::thread thr(f);
thr.join();
return 0;
}
By abstracting the notion of *synchronizes with*, the memory model
lets you talk about less stringent visiblity requirements
(release/acquire, release/consume, and relaxed) without having to
repeat their definitions everywhere they apply.
--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]