Atomic pointers in C ++ and passing objects between threads

My question includes std :: atomic and the data this pointer points to. If in stream 1 I have

Object A;
std:atomic<Object*> ptr;
int bar = 2;
A.foo = 4;  //foo is an int;
ptr.store(*A);

and if in stream 2 I noticed that ptr points to A, is it possible to guarantee that ptr-> foo is 4 and bar is 2? The default memory model for an atomic pointer (sequentially consistent) ensures that assignments on a non-atomic (in this case A.foo) that occur before the atomic storage will be visible to other threads before it sees the destination of the same atomic object. for both cases?

If this helps or matters, I use x64 (and I only care about this platform), gcc (with a version that supports atomization).

+4
source share
2 answers

Answer yes and maybe no

The principles of the memory model:

C ++ 11 atomics uses the default order in memory order std::memory_order_seq_cst, which means that operations are sequentially sequential .

The semantics of this is that the ordering of all operations is performed as if all these operations were performed sequentially:

  • 32.3 ++ , : " S memory_order_seq_cst, ", , memory_order_seq_cst , , S, , memory_order_seq_cst. "

  • 1.10/5 , : " (...), . , ".

- !

, .

, :

(thread 1) A.foo = 10; 
(thread 1) A.foo = 4;     //stores an int
(thread 1) ptr.store(&A); //ptr is set AND synchronisation 
(thread 2) int i = *ptr;  //ptr value is safely accessed (still &A) AND synchronisation

i 4. ptr , thread (2) &A . , , ptr, ( " " ).

, :

(thread 1) A.foo = 4;     //stores an int
(thread 1) ptr.store(&A); //ptr is set AND synchronisation 
(thread 1) A.foo = 8;     // stores int but NO SYNCHRONISATION !! 
(thread 2) int i = *ptr;  //ptr value is safely accessed (still &A) AND synchronisation

undefined. 4 - , , , ptr, . , . 8.

*ptr = 8; A.foo=8;, : i 8.

, :

void f1() {  // to be launched in a thread
    secret = 50; 
    ptr = &secret; 
    secret = 777; 
    this_thread::yield();
}
void f2() { // to be launched in a second thread
    this_thread::sleep_for(chrono::seconds(2));
    int i = *ptr; 
    cout << "Value is " << i << endl;
}

, - , . , ptr . .

, .

:

// Thread (1): 
std:atomic<Object*> ptr;
A.foo = 4;  //foo is an int;
ptr.store(*A);

// Thread (2): 
Object *x; 
x=ptr;      // ptr is atomic but x not !  
terrible_function(ptr);   // ptr is atomic, but the pointer argument for the function is not ! 
+10

++ - 11 /.

, , , .

.

+4

All Articles