Main / CoursesAAMultiThreadingLinux

NOTE: I compile using g++ t.cc -lpthread -lrt

#include <iostream>
#include <pthread.h>
#include <math.h>

using namespace std;

// Stores the arguments passed around in the code below.
struct Args {
  pthread_mutex_t* mutex;
  int thread_num;
  double start;
  double end;
  double sum;
  Args(pthread_mutex_t* _mutex, int _thread_num, double _start, double _end)
    : mutex(_mutex), thread_num(_thread_num), start(_start), end(_end), sum(0) {  }
};

// Adds up the numbers (increments of 1) from start to end.
void* GetSum(void* p) {
  Args* args = (Args *) p;
  // We print the following message under mutex lock so it is not interrupted.
  pthread_mutex_lock (args->mutex);
  cout << "Starting thread: " << args->thread_num << " sum range "
       << args->start << " to " << args->end << endl;
  pthread_mutex_unlock (args->mutex);

  for (double i = args->start; i < args->end; i++) {
    // Print out our progress. We don't bother mutex locking here.
    if (fmod(i, 1e7) < 0.1) { 
      cout << "T(" << args->thread_num << ") at: " << i << endl;
    }
    args->sum += i;
  }
}

void RunSingleThread(pthread_mutex_t* mutex, double max) {
  Args args0(mutex, 0, 0, max);
  GetSum(&args0);
  cout << "Single Threaded - Sum: " << args0.sum << endl << endl;
}

void Run2Threads(pthread_mutex_t* mutex, double max) {
  pthread_t tid[2];

  Args args0(mutex, 0, 0, max / 2);
  Args args1(mutex, 1, max / 2 + 1, max);

  // Create and start two separate threads to compute the sums.
  pthread_create(&(tid[0]), NULL, &GetSum, &args0);
  pthread_create(&(tid[1]), NULL, &GetSum, &args1);

  // Waits until both threads are done.
  pthread_join(tid[0], NULL);
  pthread_join(tid[1], NULL);

  // Total the partial sums from the two threads and output the result.
  cout << "Multithreaded - Sum: " << args0.sum + args1.sum << endl << endl;
}

int main(int argc, char* argv[]) {
  double max = 3e8;

  pthread_mutex_t mutex;
  pthread_mutex_init(&mutex, NULL);

  double start = (double) clock() / (double) CLOCKS_PER_SEC;
  RunSingleThread(&mutex, max);
  double end_single = (double) clock() / (double) CLOCKS_PER_SEC;
  Run2Threads(&mutex, max);
  double end_dual = (double) clock() / (double) CLOCKS_PER_SEC;

  pthread_mutex_destroy(&mutex);

  cout << end_single - start << " s (single thread) " << endl
       << (end_dual - end_single) / 2 << " s (dual threads) " << endl;
  return 0;
}