Project 3 Producer Consumer Problem

advertisement
Producer-Consumer Problem
CIS 3207 Spring 2015
Lab Project 3
In this assignment, you are going to implement a solution to the producer-consumer problem. This
assignment will help you understand issues in synchronization of concurrent threads. A general form of
a high level algorithm that can be used to implement a producer-consumer program is given later in
this document.
In this project, you will implement the solution to the producer-consumer problem, where producers
and consumers are threads, using two different approaches. The first approach is the more traditional
approach using synchronization between producers and consumers and between producers and
between consumers as shown in the high level algorithm that is included later in this document.
The second implementation is to use an approach that is similar to the solution of the problem using a
‘monitor’ with condition variables to implement the producer and consumer operations. This method
also helps avoid issues due to spurious wakeups for full and empty buffer conditions. (one brief source
of information about spurious wakeups is found at http://en.wikipedia.org/wiki/Spurious_wakeup ).
Outline of the problem:
General Problem Statement
The problem consists of many (minimum of 4) producer threads and many (minimum of 3)
consumer threads sharing a (memory) buffer with multiple (minimum of 20) slots (storage cells);
each producer deposits one element (of whatever item each produces) into one slot of the buffer
each time it “produces”, and each consumer extracts one element from the buffer each time it
“consumes”. The buffer is treated as a circular queue, with insertions into one end of the queue, and
extractions from the queue from the other end.
Your program should save critical event information to a log file. You should design your program to
log the event occurrences that can demonstrate that the program (producer and consumer threads)
are executing correctly, that no task has interfered with the other task as it is manipulating the
buffer, and that the buffer is not corrupted by the work of the threads. Part of your design is to
consider possible error conditions and to dynamically test to ensure that you have avoided these
conditions.
You will need to vary the speeds of the producer (consumer) depositing (fetching) elements, and
demonstrate proper buffer storage and access as the intervals increase and decrease. [timers or
timing loops can be used to implement speed control.]
1. For the first (more traditional) approach to solve the problem, you should use mutex (binary
semaphore) objects to implement mutual exclusion between producers and between
consumers. You need to ensure that two tasks cannot access the same buffer slots at the same
time.
In addition, a producer task may not write to the buffer if it is full, and a consumer task may not
read from the buffer if it is empty. These activities will require that the producer or consumer
blocks, until the operation it requires can be completed. This means that a producer blocked on
a full buffer can be released from its block because a subsequent consumption has emptied a
slot, or a consumer that is blocked on an empty buffer can be released from its block because a
producer subsequently deposits a value in the buffer. In order to implement these “block and
1
Producer-Consumer Problem
CIS 3207 Spring 2015
release” capabilities, you should use general semaphores for synchronization.
a. We suggest that you begin your development by solving the one consumer, one producer
problem with a shared multiple storage cell buffer and then build the full solution.
We will discuss both the single producer/ single consumer solution and the multiple producer /
multiple consumer solution in class and looked at the high level algorithms for solution in both
cases.
You can use this following ‘high level’ algorithm for your implementation of the single producer/
single consumer version --you can also design your own solution – and then build your multiple
producer/ multiple consumer version from there:
full: status of the buffer, 1 is full, 0 is not;
empty: status of the buffer, 1 is empty, 0 is not;
mutex: binary semaphore
producer:
produce item m;
P(mutex);
if(full)
:
//handle “wait for not full”
else
insert data into buffer;
:
// if buffer was empty, “release blocked consumer”
V(mutex);
consumer:
P(mutex);
if(empty)
:
//handle “wait for not empty”
else
extract data from buffer;
:
//if buffer was full, “release blocked producer”
V(mutex);
Consume item;
2. For the second implementation, the same functional rules apply, and you are to follow an
approach that would be used with conditional variables, except that conditional variables are
able to release the lock and sleep on the condition atomically, while you will do this in two steps.
A single mutex is used to lock access to the buffer. Each consumer and each producer has a loop
used to control waiting while a buffer is empty (consumer) and while a buffer is filled (producer).
Within the loop is the semaphore control. This loop implementation is also used to compensate
for those spurious wakeups.
a. You are being given more design and implementation responsibilities for this solution and
will need to consider how condition variables are used to guide your solution
development.
3. You will be implementing the solutions in two different operating systems – Linux and Windows
7. The first problem is to be solved using Linux. The second problem is to be solved using
2
Producer-Consumer Problem
CIS 3207 Spring 2015
Windows. This will give you experience with the two different development/test environments
and differences in system calls between these two systems. I suggest that you begin with the
high level algorithm for a single consumer producer and develop the rest of the
algorithm/solution. Then look at the Linux and Windows system calls to determine what you will
need to create/destroy threads, and create and use mutex objects and semaphores.
a. You have been working with Linux for lab project 2, so we want you to begin the project
in Linux and then use Windows to implement the solution to the second part. In Linux,
you have the Pthreads library available to you.
b. You will implement the solution to the 2nd part on a Windows system, using the library
functions or objects provided by Microsoft. The suggested environment is Visual Studio
and C/C++. MSDN is a very good source of information regarding synchronization
objects and details of how to use them.
3
Producer-Consumer Problem
CIS 3207 Spring 2015
Download