Starting from:

$25

CPEN333 - Software Systems Engineering - Lab 5 - Solved

This lab introduces the student to concepts of thread/process synchronisation communication. 

 

Introduction

Before tackling these questions, make sure you have downloaded and expanded (in the correct directory) the RTExamples zip file from the web-site. 

 

Also make sure you are familiar with the Visual C++ environment and know how to create projects, build, execute and run them. There is a handout on the web-site showing you how to create Concurrent Applications using Visual C++.

 

 

Part A - Pre-lab (no grade, no submission)

 

As part of the RTExamples folder on Canvas there is a project called Q8 – MutualExclusionUsingProcesses. Open this project in Visual Studio, rebuild the solution and run the project. Think about what it is attempting to do and explain why it fails in :-. 

 

1) A time-slicing system where both processes are run on the same CPU core 

2) A system where time-slicing is not used and both processes run on separate cores.

 

There is no need to submit your answer to points 1 and 2 above – it’s just for you to think about to develop your understanding:-

 

Now add a Mutex to correct the problem and explain why a mutex solves it and why it takes so much longer. Note you will have to reduce the incrementing to something like 400,000 for parent and child otherwise it will take “forever”. 

 

Part B – 20%

 

Create a new workspace/project and create an active class with it’s own main() thread and 3 child threads (all inside the active class).  Inside the project/program’s main(), create an instance of that active class and let it create the 3 child threads from the active class (also wait for all threads to complete at the end)

 

 

 

 

 

 Let the main() for the active class be the 1st or parent thread as follows

 

#include “rt.h”

 

 

int main(void)

{

                …                                                                            // create the 3 other child threads

 

                for(int i = 0; i < 50000; i ++) {

                                MOVE_CURSOR(5,5) ;                   // move cursor to cords [x,y] = 5,5

                                printf("Thread 1") ;

                                fflush(stdout) ;                                // force output to be written to screen now

                }

…                                                                            // wait for the 3 other child threads to end

 

                return 0 ;

}

                

(Note you could use cout instead of printf() if you like and then call cout.flush() to achieve the same things above – it’s just a matter of preference)         

 

Write the remaining threads to carry out similar tasks but change the printf() message and also change the coords to (10,20), (10,30) and (10,40). Make sure thread 1 creates the 3 other threads as child thread (as per Lab 2 & 3)

 

Problem: What do you see? Why doesn’t it work?

 

Problem: Fix the problem using :-



A C++ ’11 style Atomic_Flag and 
A Mutex  (note you should dynamically create this using the operator “new” and a pointer, all inside the active class, and delete the mutex at the end)

 

Part C – 40%

 

Monitors provide a much safer way for concurrent tasks to access a non-sharable resource. Essentially a monitor is an object (based on a C++ class) with external methods/member functions and built in synchronisation to the data contained within the monitor (see lecture 9).

 

For this part of the lab you are asked to write a “Named” monitor class (see RTExamples Q8 for ideas) to protect access to the terminal output window. That is, it is a development of Part B above where threads handled the synchronisation themselves. The monitor only need provide one interface function WriteToScreen() that can be called by a thread to output a message to the screen at specified coordinates (i.e. that data should be passed to the interface function as arguments).

 

Build the “Named” monitor code into your solution for Part B above (it’s probably a good idea to make a copy of that project and use that to preserve the project for Part B) and adjust each thread to make use of the new monitor without have to write any synchronisation code in the thread itself.

 

Even though only threads within a single process are accessing our monitor (and thus we could get away with an “unnamed” monitor), you are being asked to create a more flexible “named” monitor for this part of the lab as it allows the monitor to be accessed across process boundaries, i.e. it will be a “system wide” monitor.

 

Part D – 40%

 

Q9 in the RTExamples zipped file contains an example of a single producer/single consumer problem. Open and build the projects and run the application, make sure you understand how it works.

 

Modify the project to become a single producer, double consumer
Modify the project to become a double producer, single consumer (uses two data pools, one for each producer and a polling algorithm in the consumer
 

Parts E and F do NOT have to be submitted to the Canvas Lab 5 drop box. The suggestion here is that you carry them out now as part of the work for assignment 1 (which will be submitted later)

 

Part E

Q6 is an example of a rendezvous problem synchronising several processes/threads. Using this as an example, add one or more rendezvous objects to your assignment 1 so that all processes and/or threads synchronise themselves (wait) for the creation of each other. That is, all processes/threads must wait until all other processes/threads are up and running and have signalled the rendezvous before proceeding with the simulation. You may want another rendezvous object to synchronise the termination of the processes/threads at the end of the simulation



Part F

Introduce mutex’s and/or semaphores and/or producer consumer solutions into your 1st assignment (as appropriate, depending upon the architecture given to you) to protect the resources.

 

More products