nspecified state on construction (either set or clear),
// unless it is explicitly initialized to ATOMIC_FLAG_INIT.
std::atomic_flag winner = ATOMIC_FLAG_INIT;
void count1m(int id)
{
while (!ready) { std::this_thread::yield(); } // wait for the ready signal
for (volatile int i = 0; i < 1000000; ++i) {} // go!, count to 1 million
if (!winner.test_and_set()) { std::cout << "thread #" << id << " won!\n"; }
};
int test_atomic_atomic()
{
// atomic::atomic: Constructs an atomic object
std::vector threads;
std::cout << "spawning 10 threads that count to 1 million...\n";
for (int i = 1; i <= 10; ++i) threads.push_back(std::thread(count1m, i));
ready = true;
for (auto& th : threads) th.join();
return 0;
}
/////////////////////////////////////////////////////////////////////
// reference: http://www.cplusplus.com/reference/atomic/atomic/compare_exchange_weak/
// a simple global linked list:
struct Node { int value; Node* next; };
std::atomic list_head(nullptr);
void append(int val)
{ // append an element to the list
Node* oldHead = list_head;
Node* newNode = new Node{ val, oldHead };
// what follows is equivalent to: list_head = newNode, but in a thread-safe way:
while (!list_head.compare_exchange_weak(oldHead, newNode))
newNode->next = oldHead;
}
int test_atomic_compare_exchange_weak()
{
// atomic::compare_exchange_weak: Compares the contents of the atomic object's contained value with expected:
// -if true, it replaces the contained value with val(like store).
// - if false, it replaces expected with the contained value
// spawn 10 threads to fill the linked list:
std::vector threads;
for (int i = 0; i<10; ++i) threads.push_back(std::thread(append, i));
for (auto& th : threads) th.join();
// print contents:
for (Node* it = list_head; it != nullptr; it = it->next)
std::cout << ' ' << it->value;
std::cout << '\n';
// cleanup:
Node* it; while (it = list_head) { list_head = it->next; delete it; }
return 0;
}
///////////////////////////////////////////////////////////////
// reference: http://www.cplusplus.com/reference/atomic/atomic/exchange/
std::atomic winner_(false);
void count1m_(int id)
{
while (!ready) {} // wait for the ready signal
for (int i = 0; i<1000000; ++i) {} // go!, count to 1 million
if (!winner_.exchange(true)) { std::cout << "thread #" << id << " won!\n"; }
};
int test_atomic_exchange()
{
// atomic::exchange: Replaces the contained value by val and returns the value it had immediately before
std::vector threads;
std::cout << "spawning 10 threads that count to 1 million...\n";
for (int i = 1; i <= 10; ++i) threads.push_back(std::thread(count1m_, i));
ready = true;
for (auto& th : threads) th.join();
return 0;
}
/////////////////////////////////////////////////////////
// reference: http://www.cplusplus.com/reference/atomic/atomic/load/
std::atomic foo(0);
void set_foo(int x)
{
foo.store(x, std::memory_order_relaxed); // set value atomically
}
void print_foo()
{
int x;
|