------------------------------------------------------------------------------
MC logo
C++-11 Threading Example
[^] Threads
------------------------------------------------------------------------------
thrd.cpp
//
// A thread demo in C++ using the thread facility defined in the C++-11
// standard.  The layout is much like pthreads, but the interface is much
// cleaner.  As the other thread examples, the main declares a certain amount of
// "resources" (just an integer number) then starts two threads which
// "work through" the resources (mostly by printing that they did).  
//
#include <cstdlib>
#include <iostream>
#include <string>
#include <thread>
#include <mutex>

// This is for the Unix gitpid() used for randomization.  It has nothing to do
// with the C++-11 threading.
#include <unistd.h>

using std::string;
using std::cout;
using std::endl;

/* Shared data.  */
int depot;

/* Used tosynchronize access to the resource depot. */
std::mutex depot_sync;

/* Thread function.  Takes a string to print and range for the random number
   generator for the number of resources used. */
void thbod(string topr, int low, int high)
{
        while(1)
        {
                /* Choose a random number in range. */
                int amt = rand() % (high - low + 1) + low;

                /* Acquire the lock and obtain needed resource. */
                depot_sync.lock();
                if(depot < amt) amt = depot;
                depot -= amt;
                depot_sync.unlock();

                /* When the resource is exhausted, we're done. */
                if(amt == 0) return;

                /* Do that much "work." */
                while(amt--) { 
                        cout << "[" << topr << "]"; 
                        cout.flush();
                }
                cout << endl;
        }
}

/* Main starts two threads and waits for them to end. */
main()
{
        /* Seed the random number generator to vary behavior. */
        srand(time(0) ^ 387*getpid());

        /* Create the threads. Both start running thbod, and finish when
           the function returns.  The depot provides resources for the
           the threads to run. */
        depot = 3000;

        /* Two thread objects.  These declarations both create the objects and
           call the indicated function (thbod in both cases) in a new thread
           of control. */
        std::thread th1(thbod, "Z", 14, 18);
        std::thread th2(thbod, "EE", 8, 12);

        /* Wait for each of them to be done. */
        th1.join();
        cout << "First Done" << endl;
        th2.join();
        cout << "Second Done" << endl;
}