CSS 503
Lab Work 2: Thread Synchronization

Professor: Munehiro Fukuda
Lab work date: See the syllabus


1. Purpose

This laboratory work intends to familiarize you with pthread synchronization. You will code a program that suspends and resumes one after another thread.

2. System Calls

You will use the following pthread functions. Check the specification of each function using man.

3. Statement of Work

The following code is a template for allocating a given number of condition variables and thereafter launching a given number of child threads, each thread i waiting on the corresponding condition variable cond[i] and signaled by the thread i - 1, which results in suspending and resuming one after another thread 10 times.
   #include <iostream> // cout                                                                         

   using namespace std;

   int nThreads;            // #threads
   int turn;                // turn points which thread should run
   pthread_mutex_t mutex;   // a lock for this critical section
   pthread_cond_t *cond;    // array of condition variable[nThreads]

   void *thread_func( void *arg ) {
     int id = ((int *)arg)[0];                  // this thread's identifier
     delete (int *)arg;

     for ( int loop = 0; loop < 10; loop++ ) {  // repeat 10 times
       // enter the critical section

       while ( turn != id ) {
         // wait until the (id - 1)th thread signals me.
       }
       cout << "thread["<< id << "] got " << loop << "th turn" << endl;
       // singal the next thread
       // leave the critical section
     }
   }

   int main( int argc, char *argv[] ) {
     // validate arguments
     if ( argc != 2 ) {
       cerr << "usage: lab2 #threads" << endl;
       return -1;
     }
     nThreads = atoi( argv[1] );
     if ( nThreads < 1 ) {
       cerr << "usage: lab1 #threads" << endl;
       cerr << "where #threads >= 1" << endl;
       return -1;
     }

     pthread_t *tid = new pthread_t[nThreads];  // an array of thread identifiers
     cond = new pthread_cond_t[nThreads];       // an array of condition variables
     turn = 0;                                  // turn points which thread should run

     for ( int i = 0; i < nThreads; i++ ) {     // start a give number (nThreads) of threads.
       int *id = new int[1];
       id[0] = i;
       pthread_create( &tid[0], NULL, thread_func, (void *)id );
     }

     for ( int i = 0; i < nThreads; i++ )       // wait for all the child threads.
       pthread_join( tid[0], NULL );
   }
The following is an execution output when running the program with 4 child threads.
   [css503@uw1-320-18 lab2]$ ./lab2 4
   thread[0] got 0th turn
   thread[1] got 0th turn
   thread[2] got 0th turn
   thread[3] got 0th turn
   ...
   thread[0] got 8th turn
   thread[1] got 8th turn
   thread[2] got 8th turn
   thread[3] got 8th turn
   thread[0] got 9th turn
   thread[1] got 9th turn
   thread[2] got 9th turn
   thread[3] got 9th turn
   [css503@uw1-320-18 lab2]$ 
Complete the thread_func() function so that the program runs as specified above. To compile your program, you need to type:
   g++ lab2.cpp -lpthread -o lab2

4. What to Turn in

Turn in the following materials at the end of class:
  1. Your lab2.cpp
  2. Your execution output
If your time runs out, you may submit it together with programming assignment 2.