// The basis of this demo is from Gemini, apparwently from andy-pearce.com // I have modified it heavly // // This was written in class, it shows what happens with no locks #include #include #include #include #include #include #include using namespace std; struct SharedDataT { unsigned int counter; pthread_mutex_t mutex; }; void DoWork(SharedDataT * shared, int iterations, bool doMutex) ; void Usage(string name); int main(int argc, char * argv[]) { bool doMutex {true}; int processes{5}; int iterations{1000}; bool argsError{false}; bool verbose{false}; int tmp; int opt; while ((opt = getopt(argc, argv, "vhmp:i:")) != -1) { switch(opt) { case 'v': verbose = true; break; case 'h': argsError = true; break; case 'm': doMutex = false; break; case 'p': tmp = stoi(optarg); if (tmp > 1) { processes = tmp; } break; case 'i': tmp = stoi(optarg); if (tmp > 1) { iterations = tmp; } break; default: argsError = true; } } if (argsError) { Usage(argv[0]); } if (verbose) { cout << endl; cout << "Do Mutex " << boolalpha << doMutex << endl; cout << "Processes: " << processes << endl; cout << "Iterations: " << iterations << endl; cout << endl; } int prot {PROT_READ | PROT_WRITE}; int flags{MAP_SHARED| MAP_ANONYMOUS}; SharedDataT * shared = static_cast(mmap(NULL, sizeof(struct SharedDataT), prot, flags, -1, 0)); shared->counter = 0; for (int i = 0; i < processes; ++i) { if (fork() == 0) { DoWork(shared, iterations, doMutex); return 0; } } // wait for all workers to finsh for (int i = 0; i < processes; ++i){ wait(NULL); } cout << "The count is " << shared->counter << endl; cout << "It should be " << processes * iterations << endl; munmap(shared, sizeof(SharedDataT)); return 0; } void Usage(string name) { cout << endl; cout << "Usage " << name << endl; cout <<"\t-m ....... do not use mutex" << endl; cout <<"\t-i n ....... exch process should perform n iterations" << endl; cout <<"\t-p n ....... start p processes" << endl; cout <<"\t-v ....... print configuration status" << endl; cout <<"\t-h ....... print help" << endl; cout << endl; } void DoWork(SharedDataT * shared, int iterations, bool doMutex) { for (int j = 0; j < iterations; ++j) { usleep(rand() % 10); shared->counter++; } }