/*
    must compile with -lpthread option so the compiler knows to load 
    the pthread library  (/usr/lib/libpthread.so):wq
*/


#include <unistd.h>    // for sleep()
#include <pthread.h>
#include <stdio.h>
#include <assert.h>
#include <iostream>
using namespace std;

int global = 0;

void *thread_code(void *params)
{
    // usually don't want to change globals w/o assuring no other 
    // process is in the middle of changing it
    global += 1;

    int num = *((int *) params);
    cout << "hello from thread_code(" << num << ") global = " 
         << global << endl;

    sleep(2); // sleep to demonstrate other threads executing

    pthread_exit(0);
}

int main()
{
    const int NUM_THREADS = 3;
    pthread_t tid;  // thread id
    pthread_attr_t attr; // struct to hold thread attributes

    // this usually works so we can do error checking using an assert
    assert(pthread_attr_init(&attr) == 0); // fill attr struct w/defaults

    for (int i = 0; i < NUM_THREADS; i++)
    {
        int *num = new int(i);
        cout << "parent about to create thread " << i 
             << " global = " << global << endl;
        if (pthread_create(&tid, &attr, thread_code, num) != 0)
        {
            perror("pthread_create() failed");
            exit(1);
        }
    }
    for (int i = 0; i < NUM_THREADS; i++)
    {
        cout << "parent waiting for thread " << i << " to end" << endl;
        pthread_join(tid, NULL);
    }
}

