#include <semaphore.h>
#include <pthread.h>
#include <iostream>
using namespace std;

sem_t mutex;  // semaphore must be initialized using sem_init() (see below)

// code that will be executed by a thread
void *thread_code(void *arg)
{
    cout << "start of thread... about to call sem_wait()" << endl;
    sem_wait(&mutex);
    cout << "end of thread " << endl;
    return 0;
}

int main()
{
    pthread_t child_thread_id;
    int error;

    if (sem_init(&mutex, /* pshared = */ 0, /* value = */ 1))
    {
        perror("sem_init(mutex) in main()");
        exit(1);
    }

    sem_wait(&mutex);

    // create a new thread to execute thread_code()
    if (error = pthread_create(&child_thread_id, 
                                /* use default attributes: attr = */ NULL,
                                thread_code,
                                /* thread_code argument = */ 0)
       )
    {
        cerr << "pthread_create() failed: " << strerror(error) << endl;
        exit(1);
    }

    cout << "main() blocked on read: press return to resume main()..." << endl;

    // block on read from standard input.  Discard the character that is read
    getchar();

    cout << "main() about to call pthread_join()..." << endl;

    sem_post(&mutex);

    void *result;
    if (error = pthread_join(child_thread_id, &result))
    {
        cerr << "pthread_join() failed: " << strerror(error) << endl;
        exit(1);
    }
    else
    {
        cout << "main() after call to pthread_join(): "
             << "thread exit status = " << (int) result << endl;
    }

    cout << "main() calling exit(0)" << endl;
    exit(0);
}


