#include #include #include #include #include using namespace std; // In this version, rather than synchronize the data, // we synchronize execution of the code, in particular, // the increase_mutex method mutex globalMutex; // mutex to control exeuction of method atomic atomic_counter (0); int unsync_counter = 0; void increase_atomic(int n) { for (int i=0; i lock(globalMutex); // safe mutex acquistion for (int i=0; i lock(globalMutex); // safe mutex acquistion ++unsync_counter; } } void waitForThreads(vector &threads) { cout << "wait for all threads..." << endl; int joined = 0; for (auto & th : threads) { th.join(); joined++; } threads.clear(); cout << "join'ed " << joined << " threads" << endl; } int main (int argc, char *argv[]) { vector threads; cout << endl << "increase atomic counter with 10 threads..." << endl; for (int i=1; i<=10; ++i) threads.push_back(thread(increase_atomic, 10000000)); waitForThreads(threads); cout << "atomic counter: " << atomic_counter << '\n'; cout << endl << "increase unsynchronized counter with 10 threads, coarse grained..." << endl; for (int i=1; i<=10; ++i) threads.push_back(thread(increase_mutex_coarseGrained, 10000000)); waitForThreads(threads); cout << "unsync counter: " << unsync_counter << '\n'; unsync_counter = 0; cout << endl << "increase unsynchronized counter with 10 threads, fine grained..." << endl; for (int i=1; i<=10; ++i) threads.push_back(thread(increase_mutex_fineGrained, 10000000)); waitForThreads(threads); cout << "unsync counter: " << unsync_counter << '\n'; return 0; }