$24
1. Purpose
This lab intends to familiarize you with pthread synchronization. Your task is to code a program that suspends and resumes one thread after another.
2. System Calls
You will need to use the following pthread functions. Check the specification of each function using man.
pthread_create: creates a child thread that starts from a given function.
pthread_join: suspends the calling thread until one of its childrent gets terminated.
pthread_mutex_lock: enters a critical section.
pthread_cond_wait: waits on a given condition variable.
pthread_cond_signal: signals one of the threads waiting on a given condition variable.
pthread_mutex_unlock: leavs a critical section.
Statement of Work
The following code is a template for allocating a given number of condition variables and then launching a given number of child threads. Each thread i will be waiting on the corresponding condition variable cond[i] and signaled by the thread i - 1, which results in suspending and resuming one thread after another 10 times.
#include
<stdio.h
#include
<pthread.h
#include
<stdlib.h
#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.
}
1 of 2 , 5:01 PM
OneNote Online https://onenote.officeapps.live.com/o/onenoteframe.aspx?ui=en-US&rs=...
cout << "thread["<< id << "] got " << loop << "th turn" << endl;
signal 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 nThreads number
of threads
int *id =
new int[1];
id[0] = i;
pthread_create( &tid[i], NULL, thread_func, (void *)id );
}
for ( int i = 0; i < nThreads; i++ )
pthread_join( tid[i], NULL );
}
// wait for all the child threads.
The following is the execution output when running the program with 4 child threads:
[css503@uw1-320-18 lab3]$ ./lab3 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 lab3]$
Complete thread_func() so that the program runs as specified above. To compile your program, use the following command:
g++ lab3.cpp -lpthread -o lab3
4. What to Turn in
Turn in the following materials at the end of class:
Source code file lab3.cpp
Your execution output (you can take a screenshot and copy-paste it on a document file)
2 of 2 , 5:01 PM