vendredi 5 mars 2021

Don't really get the logic of std::atomic::compare_exchange_weak and compare_exchange_strong

I've read https://en.cppreference.com/w/cpp/atomic/atomic/compare_exchange

Atomically compares the object representation (until C++20)value representation (since C++20) of *this with that of expected, and if those are bitwise-equal, replaces the former with desired (performs read-modify-write operation). Otherwise, loads the actual value stored in *this into expected (performs load operation).

So as I understand the code like

bool expected=true;
extern atomic<bool> b = false; 
void foo ()
{
//
    while(!b.compare_exchange_weak(expected, false));
//
}

after the loop will run once(ignoring spurious failure) it will fail, and will write to expected false, so on the second iteration compare_exchange_weak will return success, though b hasn't been changes to true. But what's the point of all this? I though I could use this as a lock for synchronization, waiting for other thread to change b, but now I can't think of a usage of this.

Example from the cppreference also shows that after two calls compare_exchange_strong will succeed.

#include <atomic>
#include <iostream>
 
std::atomic<int>  ai;
 
int  tst_val= 4;
int  new_val= 5;
bool exchanged= false;
 
void valsout()
{
    std::cout << "ai= " << ai
          << "  tst_val= " << tst_val
          << "  new_val= " << new_val
          << "  exchanged= " << std::boolalpha << exchanged
          << "\n";
}
 
int main()
{
    ai= 3;
    valsout();
 
    // tst_val != ai   ==>  tst_val is modified
    exchanged= ai.compare_exchange_strong( tst_val, new_val );
    valsout();
 
    // tst_val == ai   ==>  ai is modified
    exchanged= ai.compare_exchange_strong( tst_val, new_val );
    valsout();
}

Result:

ai= 3  tst_val= 4  new_val= 5  exchanged= false
ai= 3  tst_val= 3  new_val= 5  exchanged= false
ai= 5  tst_val= 3  new_val= 5  exchanged= true

Aucun commentaire:

Enregistrer un commentaire