A mutex lock is meant to be taken and released, always in that order, by each task that uses the shared resource it protects. In general, semaphores should not be used to enforce mutual exclusion. The correct use of a semaphore is to signaling from one task to another, i.e., a task either signal or wait, not both.
In this assignment you will solve the rendezvous problem using semaphores. This problem clearly demonstrates the type of synchronization that can be provided by semaphores.
The provided code has been developed and tested on the department Linux system and macOS. Most likely you will be able to use any resonable modern verion of Linux.
module-4/mandatory/src/rendezvous.c
In the terminal, navigate to the module-4/mandatory
directory. Use make to compile the program.
$ make
The executable will be named rendezvous
and placed in the bin
sub directory. Run the program from the terminal.
$ ./bin/rendezvous
Run the programs several times and study the source code. Think about the following questions.
Rendezvous or rendez-vous (French pronunciation: [ʁɑ̃devu]) refers to a planned meeting between two or more parties at a specific time and place. 1
We now want to make the two threads have a rendezvous after each iteration, i.e., the two threads A and B should perform their iterations in lockstep. Lockstep means that they both first perform iteration 0, then iteration 1, then iteration 2, etc. For each iteration the order between A and B should not be restricted.
An example for itertaion 0 and 1 is shown below.
In the above example, the two threads A and B compete (execute concurrently) and one will be first to reach the rendezvous point. For iteration 0, thread B is first to reach the rendezvous point and must wait for thread B to also reach the rendezvous point. Once the two threads have been synchronized at the rendezvous point, they once again compete during iteration 1 to be the first to reach the next rendezvous point. In the above example, for iteration 1, thread A is first to reach the rendezvous point and must wait for thread B.
Use the psem semaphores to enforce rendezvous between the two threads. .
How many semaphores are needed to make the two threads have a rendezvous after each iteration?
For simplicity, declare all psem_t
semaphore varaibles globally.
Initialse your semaphore(s) in the beginning of main()
.
At the end of main()
, don’t forget to destroy any semaphores you have initialized.
Compile and run the program.
$ make
$ ./bin/rendezvous
This is an example of an invalid execution trace.
A0
B0
B1
A1
B2
B3 // ERROR: should be A2
A2
This is an example of a valid execution trace.
A0
B0
B1
A1
B2
A2
A3
B3
Change the threads sleeping durations.
Here are a few examples of questions that you should be able to answer, discuss and relate to the source code of you solution during the code grading.