//* Thread Synchronization in C++ 11 *

#ifdef _MSC_VER // for MS Visual Studio compilers - to allow "classic" insecure printf and scanf #define _CRT_SECURE_NO_WARNINGS #endif #include <stdlib.h> #include <stdio.h> #include <thread> #include <mutex> using namespace std; // g++ -std=c++0x -ptrhead threads.cpp // ^^^ still experimental support! // ^^^^^^^^ for now pthread is needed as it is not included in standard c++ library typedef struct { unsigned long int duration; char print_debug; } parameters_t; mutex Mutex_for_GlobalSum; // default class constructor for mutex called automatically when global variable is declared volatile unsigned long int GlobalSum; /* data is shared by the thread(s) */ /* the threads runs in these separate functions */ void Summation1(parameters_t Param) { unsigned long int i, j; // local variables might be quicker to access and/or easier to optimize for a compiler const unsigned long int upper = Param.duration; const char prn = Param.print_debug; for (i = 1; i <= 1000; i++) { for (j = 1; j <= upper; j++) { Mutex_for_GlobalSum.lock(); GlobalSum++; Mutex_for_GlobalSum.unlock(); } fprintf(stdout, "%c", prn); fflush(stdout); } } void Summation2(parameters_t Param) { unsigned long int i, j; // local variables might be quicker to access and/or easier to optimize for a compiler const unsigned long int upper = Param.duration; const char prn = Param.print_debug; for (i = 1; i <= 1000; i++) { for (j = 1; j <= upper; j++) { // Mutex_for_GlobalSum.lock(); // GlobalSum--; // Mutex_for_GlobalSum.unlock(); { lock_guard<mutex> lock(Mutex_for_GlobalSum); // alternatively LOCK_GUARD unlocks automatically when it goes out of scope GlobalSum--; } } fprintf(stdout, "%c", prn); fflush(stdout); } } int main(int argc, char *argv[]) { parameters_t ThreadParam1; parameters_t ThreadParam2; long int Param; // do some basic error checking if (argc != 2) { fprintf(stderr,"Use: \"%s <DURATION>\"\n or enter the duration now\n\n" "Loop count = ", argv[0]); fscanf(stdin," %ld", &Param); // <- MSVS compiler warning is irrelevant here and can be avoided } else { Param = atol(argv[1]); } if (Param < 0) { fprintf(stderr, "an integer >= 0 is required \n"); return -1; } ThreadParam1.duration = Param; ThreadParam1.print_debug = 'x'; ThreadParam2.duration = Param; ThreadParam2.print_debug = 'o'; // create the thread thread Thread1( Summation1, ThreadParam1 ); // class constructor called here thread Thread2( Summation2, ThreadParam2 ); // class constructor called here Thread1.join(); Thread2.join(); if (GlobalSum==0) fprintf(stdout,"sum = %ld\n", GlobalSum); else fprintf(stdout,"sum = %ld (Shouldn\'t it be 0\a?)\n", GlobalSum); // class destructors called here automatically return(0); }