Search⌘ K
AI Features

Discussion: Back from the Future

Explore how unsynchronized threads can cause data races and undefined behavior in C++. Understand why synchronization is essential using mutexes or std::atomic. Learn methods to detect data races with tools like ThreadSanitizer and best practices to write safe concurrent code.

Run the code

Now, it’s time to execute the code and observe the output.

C++ 17
#include <future>
#include <iostream>
int main()
{
char counter = 0;
auto future1 = std::async(std::launch::async, [&]()
{
counter++;
});
auto future2 = std::async(std::launch::async, [&]()
{
return counter;
});
future1.wait();
// Cast to int to print it as a numerical value rather than a character
std::cout << (int)future2.get();
}

Understanding the output

When two unsynchronized threads access the same memory location and at least one of these accesses is a modification, we have a data race. This program launches two threads, one that modifies the counter and one that reads it. Since we have made no effort to synchronize the two threads, the program has a data race.

Undefined behavior

If we run this program on our machine, we’re very likely to see either 0 or 1, depending on which thread gets to counter first. The counter is a single byte, so we’re not likely to see, for example, any half-written values. Either the counter++ operation happens entirely before the second ...