Preliminaries
Set up a bare repository on stu.cs.jmu.edu based on the instructions
in the CS 361 Submission Procedures,
using the name lab8-synch.git
.
Implementation requirements: Protecting critical sections
For this first part, your goal is to protect a critical section created by
a nested loop. The inner-most loop adds 1 to a shared variable then
subtracts 1 from it. The end result should be 0 if this critical
section is protected. Your task is to use a lock as needed. You will also
need to set up two threads to run concurrently and perform this
calculation.
- Edit the
run()
function in mutex.c
to
create then join two threads, each of which run the
runner()
function from the same file.
- Use the lock to synchronize access to the shared variable in
runner()
. The base distribution uses a NULL
pointer for shared
. You need to change this to get the
reference from the thread arguments. Note that you can place the
locking and unlocking function calls in multiple places. One of the unit
tests includes a timing constraint that you must pass: Correct placement
of the lock will result in parallel execution that is at least three
times as fast as the sequential execution, but no more than six
times as fast.
Due to the unpredictable nature of threads and the workload on
stu
, it is possible that the timing tests might fail
occasionally. If you run it again without recompiling and it passes,
then that is fine.
For the second part, you will use two semaphores to control the timing
of two threads to produce "PING!"
and "PONG!"
messages back and forth several times. For a correct implementation,
these messages should alternate every line; there should never be
multiple lines in a row of the same message. The semaphores can ensure
this happens.
- Edit the
ping()
function in pingpong.c
to create and initialize the semaphores. You will need to
determine the initial values. This thread should then
create the pong()
thread, passing references to both
semaphores, then enter a loop to alternate messages. Complete the
rest of the code based on the embedded comments.
- Next, implement the
pong()
thread based on the
comments. This code should be very similar to the loop in the
pong()
function.
In the final implementation of this lab, the "PING!
message
should always appear first. After the alternating messages, the
"PONG: Game over"
message should appear before the
"PING: Game over"
message. The timing of this last
alternation arises by having the parent thread join the child.
For completeness, be sure to clean up the semaphores with
sem_close()
.