Concurrency 5, atomics - C++11, 12 of n

1) The high level interfaces
Concurrency 5, atomics - C++11, 12 of n_第1张图片
Footnote: compare_exchange_strong's implementation pseudocode :
bool compare_exchange_strong (T& expected, T desired)
{
    if (this->load() == expected) {
        this->store(desired);
        return true;
    }
    else {
        expected = this->load();
        return false;
    }
}
The weak form may spuriously fail so that it returns false even when the expected value is present. But the weak form is sometimes more efficient than the strong version.

What does atomic<>::store() mean by default ?
The store() operation performs a so-called release operation on the affected memory location, which by default ensures that all prior memory operations, whether atomic or not, become visible to other threads before the effect of the store operation.

What does atomic<>::load() mean by default ?
The load() operation performs a so-called acquire operation on the affected memory location, which by default ensures that all following memory operations, whether atomic or not, become visible to other threads after the load operation.

2) The low level interfaces
Concurrency 5, atomics - C++11, 12 of n_第2张图片

3) In order to compatible with C, the atomic header defines the following alias.

Concurrency 5, atomics - C++11, 12 of n_第3张图片
4) The memory order

std::memory_order_seq_cst (sequential consistent memory order, by default)
std::memory_order_release
std::memory_order_acquire
std::memory_order_relaxed

5) Examples
#include <atomic> // for atomics
#include <future> // for async() and futures
#include <thread> // for this_thread
#include <chrono> // for durations
#include <iostream>

long data;
std::atomic<bool> readyFlag(false);
void provider ()
{
    std::cout << "<return>" << std::endl;
    std::cin.get();
    data = 42;
    // signal readiness
    readyFlag.store(true);
}
void consumer ()
{
    // wait for readiness and do something else
    while (!readyFlag.load()) {
        std::cout.put(’.’).flush();
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
    }
    std::cout << "\nvalue : " << data << std::endl;
}
int main()
{
    auto p = std::async(std::launch::async,provider);
    auto c = std::async(std::launch::async,consumer);
}


Note: always should initialize atomic objects because the default constructor does not fully initialize it (it’s not that the initial value is undefined, it is that the lock is uninitialized).




你可能感兴趣的:(Concurrency 5, atomics - C++11, 12 of n)