pi.cpp

URL: https://mirkwood.cs.edinboro.edu/~bennett/class/cmsc4000/spring2026/notes/ch6/code/pi.cpp
 
#include <iostream>
#include <pthread.h>
#include <iomanip>

// needs to link with -lpthread

using namespace std;

const size_t WORKER_COUNT {10};
const size_t WORK_SIZE {1'000'000'000};

struct WorkT {
    size_t first;
    size_t last;
    long double pi;
};

void * PiWorker(void * workp);

// yuck.
//  but we can clean this up soon
long double pi[WORKER_COUNT];

int main() {
     
     pthread_t workers[WORKER_COUNT];
     for(size_t i =0; i < WORKER_COUNT;  ++i) {

         pthread_t tid;
         pthread_create(&tid, nullptr, PiWorker, 
                   // Y U C K
                   // not much to do about this.
                   reinterpret_cast<void *> (
                       new WorkT{i*WORK_SIZE, (i+1)*WORK_SIZE, 0}));
         workers[i] = tid;
     }

     long double finalPi{0};

     for(size_t i = 0; i < WORKER_COUNT; ++i) {
         void * rv  ;
         cout << "Waiting for " << workers[i] << endl;
         pthread_join(workers[i],&rv);

         WorkT * work = reinterpret_cast<WorkT *>(rv);
         finalPi += work->pi;
         delete work;
     }

     cout << "PI = "  << setprecision(20) << finalPi << endl;
     return 0;
}

void * PiWorker(void * workp){

    // yuck as well.
    WorkT & work = * reinterpret_cast<WorkT *>(workp);

    cout <<  pthread_self() 
         << " working on " << work.first 
         << " to " << work.last << endl;

    int sign{-1};

    long double term = work.first * 2 + 1;
    if (work.first %2 == 0) {
       sign = 1;
    }

    work.pi = 0;

    for(size_t i = work.first; i < work.last; ++i) {
        work.pi += sign * 4.0/term;
        term += 2;
        sign *= -1;
    } 

    pthread_exit(reinterpret_cast<void *>(workp));
}