This is my first attempt at writing multithreaded C++ code and it seems to have created a data race. Here is the complete file. It was compiled as: g++ -pthread foo.cpp
#include <iostream>
#include <iomanip>
#include <thread>
const int SIZE = 5;
void mult(int x, int y) {
std::cout.width(3);
std::cout << std::right << x * y << "* ";
}
void add(int x, int y) {
std::cout.width(3);
std::cout << std::right << x + y << "+ ";
}
int main() {
int a = 0;
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
std::thread first(mult, i, j);
std::thread second(add, i, j);
first.join();
second.join();
std::cout << " | ";
}
std::cout << "\n";
}
return 0;
}
The output is scrambled in a non-reproducible manner on each run, for example:
0* 0+ | 0* 1+ | 2 0+ * | 0* 3+ | 0* 4+ |
0* 1+ | 1* 2+ | 2* 3+ | 3* 4+ | 4* 5+ |
0* 2+ | 2* 3+ | 4* 4+ | 6* 5+ | 8* 6+ |
0* 3+ | 3 4* + | 6* 5+ | 9* 6+ | 12* 7+ |
0* 4+ | 4* 5+ | 8* 6+ | 12* 7+ | 16* 8+ |
or
0* 0+ | 0* 1+ | 0* 2+ | 0* 3+ | 0* 4+ |
0* 1+ | 1* 2+ | 2* 3+ | 3* 4+ | 4* 5+ |
0* 2+ | 2* 3+ | 4* 4+ | 6* 5+ | 8* 6+ |
0* 3+ | 3* 4+ | 6* 5+ | 9* 6+ | 12* 7+ |
0* 4+ | 4* 5+ | 8* 6+ | 12* 7+ | 16* 8+ |
Is there any way around this problem? I've learned a lot about cout objects from this, but is it the rule that only one thread should be allowed to access cout at a time, especially when using iomanip?
Edit: I understand that as per: http://www.cplusplus.com/reference/iomanip/setw/ That using iomanip in this fashion may cause data races. So the question is, should this just not be attempted? Should each thread to cout be created, do its business, then joined? (i.e. no threading at all) and that's that? If so, that's fine, the main idea with concurrency would be more about having a program open multiple concurrent fstream objects, so that the user would not have to wait on that, and one thread to cout would be fine. What I'm asking is, is that the standard approach?